Какие бесплатные C++ компиляторы и IDE к ним существуют.
Компиляторы:
1) gcc. Под windows лучше всего использовать MinGW, это порт gcc на Windows платформу.
2) Visual C++ 2005 Express Edition. Прямые ссылки на скачивание: www.rsdn.ru/Forum/Message.aspx?mid=1477837#1477837
3) Digital Mars C/C++ Compilers. Довольно неплохой компилятор, но хуже соответствует стандарту чем последние gcc или VC7.1.
4) Borland free compiler. Содержит компилятор и утилиты командной строки.
5) Open Watcom C/C++.
6) LCC-Win32 (Только Си компилятор, C++ не поддерживает).
7) Microsoft Visual C++ Toolkit 2003. полноценный оптимизирующий компилятор VC7.1 без IDE и nmake. В настоящее время заменен на Visual C++ 2005 Express Edition и с сайта Microsoft недоступен, пользуйтесь поиском. Может быть более предпочтителен из-за малого веса(~30 MiB).
IDE:
1) Dev-C++. достаточно неплохая IDE для gcc(mingw). В настоящее время развивается как wxDev-C++ в виду интеграции с системой разработки GUI wxWidgets.
2) MinGW Developer Studio - IDE предназначена специально для использования совместно с MinGW. Очень удобна тем, кто разрабатывает программу под Windows и Linux одновременно, т.к. формат проектов один и остаётся только жмакнуть на кнопку компиляции и не мучиться с настройкой разных сред.
3) Code::Blocks IDE. Это наверно одна из лучших (хоть и самое молодая) IDE для бесплатных компиляторов, подерживает не только MinGW, но и Microsoft Visual C++ Toolkit 2003, Digital Mars C/C++ Compilers, Borland free compiler, Open Watcom C/C++ и Small Device C Compiler
4) Eclipse/CDT - написанные на Java, платформа для разработки IDE + плагин превращающий платформу в приспособленную для C++ среду. Информация о плагине Скачать уже готовую IDE
5) Emacs/Vim. Не для слабых духом, долгое время обучения. Преимущества - кроссплатформенность и не снившаяся другим инструментам мощь и гибкость. Официальный сайт Vim. Emacs: - официальный ftp - хороший дистрибутив для Windows
6) eVC 3/4 Бесплатные IDE от Microsoft под платформу WinCE. www.microsoft.com
7) Visual-MinGW. Распространяется под GNU лицензией. IDE оболочка очень схожа с Microsoft Visual C++ 6
8) Visual Studio 2005 Express - бесплатная версия MSVC 2005. Имеет полноценный компилятор C++ и вместе с Platform SDK и DXSDK дает достаточно возможностей для написания игр. Размер дистрибутива ~450 Мб.
9) Visual Studio 2008 Express. Идет в коплекте с уменьшенной версией Windows SDK (ранее назывался Platform SDK), содержащей только заголовки, библиотеки и основные утилиты, так что теперь нет необходимости скачивать Platform SDK отдельно.
10) NetBeans IDE. Бесплатная IDE от Sun Microsystems, написанная на Java, а потому, как и Eclipse, требует наличия JVM на компьютере пользователя. Поддерживает множество языков, в том чииле и С++. Можно скачать как дистрибутив специально для работы с С++, так и расширить уже установленную среду с помощью плагина. Поддерживает главным образом работу с компилятором MinGW. Обеспечивает широкие возможности автоматического рефакторинга кода. Использующим несколько компиляторов сразу рекомендуется также посмотреть на Scons и Boost.Build - удобные системы для сборки проектов.
Часто возникает необходимость быстро показать кому-либо, как решить небольшую задачу по программированию или как реализовать алгоритм. Можно просто скинуть в ответ кусок кода, но лучше воспользоваться одним из online-компиляторов.
Во многих из них есть возможность получить специальную ссылку на скомпилированный код. Такую ссылку можно например оставлять в комментариях к статьям. Пройдя по ней люди увидят не только сам код, но и результат работы программы.
Рассмотрим несколько вариантов online-компиляторов поддерживающих язык программирования C++
Если программа по ходу работы требует действий пользователя – выполняем их:
Если возникнут ошибки они отобразятся во вкладке compilation, которая откроется автоматически. Во вкладе options можно выбирать разнообразные параметры для компиляции, если вас не устраивают заданные по умолчанию.
Так же на этом сайте есть компилятор для Паскаль.
Сразу при входе обратите внимание на тот язык программирования, который выбран по умолчанию. Смените его при необходимости. Входящие данные внесите в stdin:
Тут очень большой выбор языков для компиляции:
Входящие данные надо прописывать в Stdin до того, как нажмете Run.
Мне понравилось, что он хранит историю компиляций. Кроме С++ здесь есть широкий выбор языков программирования для компиляции:
Спецификация vararg для C не очень хорошо продумана. Если вы передаете все аргументы функции через стек, va_start может быть реализован довольно легко, но на современных процессорах и в современных соглашениях о вызовах аргументы передаются через регистры, чтобы уменьшить накладные расходы на вызов функций. Поэтому спецификация не соответствует реальности.
Грубо говоря, ABI для x86-64, стандартизированное AMD, требует чтобы функции с переменным числом аргументов копировали все регистры в стек, чтобы подготовиться к последующему вызову va_start. Я понимаю, что у них не было другого выбора, но это все равно выглядит неуклюже.
Мне стало интересно как другие компиляторы обрабатывают функции с переменным числом аргументов. Я посмотрел на заголовки TCC и, похоже, они не совместимы с ABI x86-64. Если структура данных для varargs отличается, то функции передающие va_list (такие как vprintf) становятся несовместимыми. Или я ошибаюсь? [И я действительно ошибаюсь - они совместимы.] Я также посмотрел на Clang, но он выглядит запутанным. Я не стал читать его. Если я буду читать слишком много кода других компиляторов, это может испортить веселье от собственной реализации.
Я пытался реализовать поддержку функций, имеющих более шести параметров, но не смог закончить это за один день. В x86-64 первые 6 целочисленных параметров передаются через регистры, а оставшиеся через стек. Сейчас поддерживается передача только через регистры. Передачу через стек не сложно реализовать, но она требует слишком много времени для отладки. Я думаю в моем компиляторе нет функций, имеющих более шести параметров, так что я пока отложу их реализацию.
Еще хуже то, что в файлах ядра я использую относительно новые особенности C, такие как составные литералы и назначенные инициализаторы. Они сильно усложняют самокомпиляцию. Я не должен был использовать их, но переписывать код на простом старом C будет не продуктивно, поэтому я хочу поддерживать их в своем компиляторе. Хотя на это потребуется время.
Во-первых, лексический анализатор запоминает свою позицию чтения и когда он прерывается по непредвиденным причинам, он возвращает эту позицию. Это позволяет легко найти баг, когда компилятор не принимает корректные входные данные.
Есть опция командной строки для печати внутреннего абстрактного синтаксического дерева. Если есть ошибка в синтаксическом анализаторе, я хочу посмотреть на синтаксическое дерево.
Генератор кода позволяет широко использовать рекурсию, потому что он генерирует фрагменты ассемблерного кода, когда обходит абстрактное синтаксическое дерево. Так я смог реализовать печать мини трассировки стека для каждой строки ассемблерного вывода. Я если я замечаю что-то неправильное, я могу проследить за генератором кода, посмотрев на его вывод.
Большинство внутренних структур данных имеют функции для преобразования в строку. Это полезно при использовании printf для отладки.
Я всегда пишу юнит-тесты, когда пишу новую функцию. Даже реализовав ее, я стараюсь сохранять код компилирующимся, чтобы запускать тесты. Тесты пишутся так, чтобы выполняться за короткий промежуток времени, так что вы можете запускать их так часто, как вам хочется.
Думаю, единственная особенность, которой не хватает для самокомпиляции, это присваивание структур. Надеюсь все будет работать как задумано без особой отладки, когда она будет реализована.
Думаю, что у меня нет другого выбора, кроме использования printf для отладки, потому что второе поколение компилируется через мой компилятор, который не поддерживает отладочную информацию. Я добавил printf в подозрительных местах. Отладочные сообщения printf отображались при компиляции второго поколения, что меня несколько удивило. Я хотел чтобы отладочные сообщения выводились только когда я использую второе поколение, так что я не ожидал что вывод будет работать, когда второе поколение только создается .
Мне это напоминает фильм «Начало». Мы должны идти глубже, чтобы воспроизвести этот баг. Это забавная часть отладки самокомпилирующегося компилятора.
Я исправил много проблем, вызванных плохим качеством кода, который я писал на ранней стадии этого проекта. Это утомило меня.
Я верил, что имел все возможности для самокомпиляции, но это не правда. Нет даже префиксных операторов инкремента/декремента. Для некоторых особенностей C99 я переписал часть компилятора, чтобы сделать его более удобным для компиляции. Так как я не ожидал добраться до возможности самокомпиляции так быстро, я использовал столько новых особенностей C, сколько хотел.
Это заняло около 40 дней. Это очень короткий промежуток времени, для написания самокомпилируемого компилятора C. Вы так не думаете? Я считаю, что мой подход - вначале сделать небольшой компилятор для очень ограниченного подмножества C, и затем преобразовать его в настоящий компилятор C очень хорошо сработал. В любом случае сегодня я очень счастлив.
Смотря на свой код, даже зная что я сам написал его, я ощущаю его немного волшебным, потому что он может принять сам себя на входе и преобразовать в ассемблер.
Осталось много багов и нереализованных особенностей. Я, наверное, закончу с ними, а потом начну работу по улучшению выходного кода.
Исходный код находится . Я не знаю, стоит ли это читать, но может быть интересно посмотреть его как образец кода на языке C, который может обработать простой компилятор в 5000 строк.
Например, мой компилятор интерпретирует "\n" (последовательность обратного слеша и символа «n») в строковый литерал "\n" (в данном случае символ новой строки). Если вы подумаете об этом, вы можете счесть это немного странным, потому что он не располагает информацией о реальном ASCII коде для "\n". Информация о коде символа не присутствует в исходном коде, но передается из компилятора, компилирующего компилятор. Символы новой строки моего компилятора могут быть прослежены до GCC.
Компиляторы могут передать гораздо больше информации, чем код символа.
Эта удивительная история была представлена Кеном Томпсоном в его лекции при получении премии Тьюринга. Информация, которую Кен добавил в раннюю версию Unix компилятора давала возможность программе для входа пользователей принимать некоторые особенные пароли, так что Кен мог войти в любую учетную запись Unix. Он также сделал так чтобы компилятор распознавал собственную компиляцию и передавал хак программы для входа дочернему компилятору, так что этот бэкдор (которого не было в исходном коде) передавался из поколения в поколение. Вы не могли удалить его, даже если бы тщательно осмотрели каждую строчку исходного кода компилятора и перекомпилировали его, поскольку компилятор, который обрабатывает исходный код был заражен. Это удивительная история, не правда ли?
Техники написания парсеров - это один из моих самых полезных навыков как программиста. Он помогал мне бесчисленное количество раз.
Однако, когда я читал спецификацию языка Си, чтобы написать парсер для грамматики использующий рекурсивный спуск, я обнаружил, что некоторые производные являются леворекурсивными. Мне пришлось некоторое время подумать и открыть учебник еще раз, чтобы вспомнить, как переписать грамматику, чтобы сделать ее праворекурсивной. Устранение левой рекурсии является базовой темой в синтаксическом анализе, которая описывается в любом вводном учебнике. Но я не мог вспомнить такие элементарные вещи, так как не использовал технику на протяжении длительного периода времени.
Я снова читал Dragon Book по этой теме, не чувствуя, что я полностью ее понял. Книга слишком абстрактна, так что я не могу немедленно применить ее моем случае.
Мой компилятор в два раза медленнее чем GCC когда компилирует сам себя. Это не так плохо, как я думал. Мой компилятор генерирует жутко бесхитростный ассемблер, но такой код не медленнее на порядок.
Я вынес неявное преобразование типов из генератора кода. Они сейчас явно представлены в АСД. Это позволяет легко понять, что происходит под капотом. Я также сделал бессистемные улучшения в различных местах. Я думал, что работа была почти завершена, но в действительности существовало множество нереализованных особенностей и ошибок.
Я стал лучше понимать оптимизацию компилятора, после того как прочитал еще несколько страниц из Dragon Book. Я мог бы начать писать код, если разберусь в этом еще чуть-чуть лучше.
Моим первым предположением было: неправильное выравнивание указателя стека. Но это не так, потому что указатель стека был уже правильно выровнен по 16-байтовой границе. Я не мог найти баги в ассемблерном выводе. Я решил разделить пополам.
Я пытался компилировать каждый файл через мой компилятор, а остальное через GCC чтобы определить функцию, с которой я могу воспроизвести проблему. Но казалось, что функция не содержит ошибок. Это не функция, которая выводит сообщение об ошибке - они даже не в одном файле. Теория заключается в том, что одна функция создает неверные данные которые вызывают ошибки в других функциях.
После продолжительной бессистемной отладки, я наконец нашел причину: компилятор не инициализирует поля структуры нулями. Спецификация C требует, чтобы при инициализации структуры, поля, не инициализирующиеся значениями, компилятор должен автоматически заполнять нулями. Я знал спецификацию когда писал код (поэтому мой код зависит от этого поведения), но я забыл его реализовать. В результате некоторые поля структур инициализировались мусором вместо нулей. Мусорные данные меняются в зависимости от текущей позиции стека, поэтому изменение указателя стека случайным образом изменяло поведение программы.
В итоге, после трехдневной отладки была исправлена всего одна строка. Хотелось бы иметь какие-то средства чтобы упростить подобную отладку.
Я снова сузил поиск до конкретного файла, разделяемого пополам. Я переносил функции по очереди из одного файла в другой, чтобы найти функцию, которая была причиной проблемы. Эта функция была не маленькой, поэтому я разделял ее и переносил код в другой файл. Наконец я получил несколько строк кода. Я скомпилировал их, с помощью GCC и моего компилятора и сравнил.
Единственная разница заключалась в этом: мой компилятор проверяет все биты в регистре, чтобы определить содержит ли он булево значение true, тогда как GCC проверяет только младшие 8 бит. Таким образом, например, если значение в регистре 512 (= 2 9 или 0x100), то мой компилятор воспринимает его как true, тогда как GCC считает по-другому. GCC на самом деле возвращает некоторое очень большое число с нулями в наименее значимых 8 битах, что воспринимается как false.
Из-за этой несовместимости, цикл, который использует для проверки условия выхода функцию, скомпилированную с помощью GCC (при этом сам цикл компилируется моим компилятором) прекращается сразу же на первой итерации. В результате, макросы препроцессора не определяются. И какие-то из токенов оставались неопределенными и поэтому парсер сообщал о синтаксических ошибках при некоторых входных данных. Причина была далеко от того места, где сообщалось об ошибке, но я, наконец, отловил ее.
Спецификация x86-64 ABI имеет небольшую заметку о том, что только младшие 8 бит являются значимыми для логических возвращаемых значений. Я читал это, но в первый раз не понял что это значит, так что я даже не помнил, что такое указание существовало. Но теперь для меня это предельно ясно. У меня смешанные чувства - я узнал новые вещи, но я мог бы их узнать, не тратя на это столько времени.
Вы можете упаковать несколько переменных в небольшой области с использованием битовых полей, но компилятор все равно должен создавать пространство между ними в зависимости от их типов. Мое быстрое исследование вывода GCC выявило такие правила (конечно, без гарантии, что они правильны):
Вычисляемый goto компилируется в единую инструкцию непрямого перехода. Наверное, это легче понять в терминах ассемблера. Мой компилятор генерирует ассемблер, так что это было очень легко реализовать.
Я также реализовал функцию typeof(), которая также является расширением GCC. Обе эти функции не используются в данный момент, но это нормально, так как для их реализации потребовалось очень мало кода.
В С89 есть триграфы, которые очевидно вредны. Триграфы — трехбуквенные последовательности символов, которые преобразуются в один символов везде, где они появляются в исходном коде. Например, printf(«huh??!») выведет не «huh??!», а «huh|» потому что "??!" это триграф для "|". Это сильно сбивает с толку. У меня нет планов, поддерживать триграфы.
TCC — это маленький компилятор C, размер которого составляет от 20К до 30к строк кода. Если вы удалите поддержку архитектур кроме x86-64, количество строк, вероятно, будет около 10К-20К. Удивительно видеть, что такой маленький компилятор поддерживает такое множество функций. Фабрис Беллар , создатель ТСС, — гений.
Я несколько раз попытался прочитать исходный код TCC, но все еще не понимаю всю картину. Компиляторы это сложные программы, поэтому вы обычно хотите разбить их на небольшие управляемые части, но исходный код ТСС ощущается, как монолитный компилятор. Я не могу писать такой великолепный код. Я не знаю, хочу ли я подражать, но то что в мире есть кто-то, кто может писать такой код, действительно производит на меня впечатление.
Теги:
Иногда просто необходимо иметь быстрый доступ к компилятору какого-либо языка. Скачивать нужную программу долго, но как же тогда быть? Представляем 5 онлайн компиляторов, которые выручат в такие моменты. Интересно, что многие программисты даже не подозревают о существовании различных онлайн компиляторов и для компиляции небольшого отрезка кода им приходится скачивать десктопные IDE , которые потом приходится еще и удалять.
В этой подборке вы узнаете про 5 компиляторов, которые наверняка смогут облегчить вам жизнь, так как выполняют свою работу на отлично!
Эти два компилятора SandBox и PHPFiddle являются очень простыми, но в этом их достоинство. Вы просто заходите на сайт и получаете готовый скомпилированный код всего в пару кликов.
Единственные отличия в этих компиляторах заключаются в нескольких деталях. Дело в том, что сайт PHPFiddle имеет красивый современный дизайн и может выполнять код вместе с HTML разметкой, что порой очень кстати. SandBox таким похвастаться не может, но зато у него есть возможность выбрать версию PHP, которая вам нужна в данный момент. Поэтому вам придется добавить оба эти сайта в закладки:)
CodePad является компилятор намного более функциональным нежели предыдущие два. Он может выполнять код не только на языке PHP, но и на многих других языках программирования.
Благодаря простому дизайну, а также хорошему компилятору сайт грузится быстро даже если у вас очень плохой интернет. Это безусловно плюс, так как вы сможете воспользоваться сервисом практически откуда угодно.
Сервис Koding нельзя назвать онлайн компилятором. Это полноценная виртуальная машина, которую вы можете запустить онлайн на удаленном компьютере.
Зайдя на сайт вы можете зарегистрироваться и в облаке создать одну или несколько полноценных виртуальных машин под управлением Ubuntu 14.04 . Понятное дело, что на таких виртуальных машинах вы уже сможете компилировать все что угодно. Такое решение является отличным, но все же вам не удасться настроить все за 5-10 минут.
На самом деле, GCC GodBolt обладает достаточно простыми характеристиками, но все же он заслуживает свое место в этом ТОПе. На этом сайте вы сможете скомпилировать только код написанный на C++. При этом вы сможете добавить какие-только угодно настройки к компиляции проекта. Те, кто часто работают с C++ смогут оценить все достоинства этого компилятора.
Последнее обновление: 18.05.2017
Для создания программ на Си необходим текстовый редактор, с помощью которого можно набрать исходный код. И также необходим компилятор, который принимает файл с исходным кодом на Си и компилирует его в исполняемый файл.
В качестве компилятора мы будем использовать наиболее популярный на сегодня компилятор gcc, который доступен для разных платформ. Более подобному информацию о GCC можно получить на официальном сайте проекта https://gcc.gnu.org/ .
Набор компиляторов GCC распространяется в различных версиях. Одной из наиболее популярных версий является пакет средств для разработки от некоммерческого проекта Mingw-w64 . Для установки соответствующего пакета компиляторов загрузим файл установщика по ссылке
При запуске установщика откроется следующее окно:
Нажмем на кнопку Next > и перейдем к следующему шагу:
Если версия ОС 64-битная, то в поле Architecture следует выбрать пункт x86_64 . Остальные настройки оставим по умолчанию и нажмем на кнопку Next > . На следующем шаге укажем путь, по которому будет устанавливаться пакет:
Можно оставить настройки по умолчанию. И после перехода к следующему шагу собственно начнется установка.
После завершения установки на жестком диске по пути, которое было выбрано для установки, появятся все необходимые файлы компиляторов. В моем случае они находятся по пути C:\Program Files (x86)\mingw-w64\i686-7.1.0-posix-dwarf-rt_v5-rev0\mingw32\bin :
В зависимости от версии пакета точный путь может отличаться, но в любом случае все файлы будут располагаться по тому пути, который был указан на шаге установки.
В частности, файл gcc.exe как раз и будет представлять компилятор для языка Си.
И добавим путь к компилятору:
Итак, компилятор установлен, и теперь мы можем написать первую программу. Для этого потребуется любой текстовый редактор для набора исходного кода. Можно взять распространенный редактор Notepad++ или даже обычный встроенный Блокнот.
Итак, создадим на жестком диске папку для исходных файлов. А в этой папке создадим новый файл, который назовем hello.c .
В моем случае файл hello.c находится в папке C:\c.
Теперь определим в файле hello.c простейший код, который будет выводить строку на консоль:
#include
Для вывода строки на консоль необходимо подключить нужный функционал. Для этого в начале файла идет строка
#include
Директива include подключает заголовочный файл stdio.h, который содержит определение функции printf, которая нужна для вывода строки на консоль.
Ключевое слово int в определении функции int main(void) говорит о том, что функция возвращает целое число. А слово void в скобках указывает, что функция не принимает параметров.
Тело функции main заключено в фигурные скобки {}. В теле функции происходит вывод строки на консоль с помощью функции printf, в которую передается выводимая строка "Hello world!".
В конце осуществляем выход из функции с помощью оператора return . Так как функция должна возвращать целое число, то после return указывается число 0. Ноль используется в качестве индикатора успешного завершения программы.
После каждого действия в функции ставятся точка с запятой.
Теперь скомпилируем этот файл. Для этого откроем командную строку Windows и вначале с помощью команды cd перейдем к папке с исходным файлом:
Чтобы скомпилировать исходный код, необходимо компилятору gcc передать в качестве параметра файл hello.c:
После этого будет скомпилирован исполняемый файл, который в Windows по умолчанию называется a.exe. И мы можем обратиться к этому файлу, и в этом случае консоль выведет строку "Hello World!", собственно как и прописано в коде.