Автор Сергей Тимофеев На чтение 8 мин Просмотров 4.2к. Обновлено
Компилятор – это по сути утилита, которая занимается переводом человеческой логики языка программирования в понятный машине набор инструкций. За несколько десятилетий была построена армия компиляторов даже для узкой группы однокоренных языков C и C++. Какой компилятор C выбрать в третьем десятилетии XXI века?
Содержание
Компилятор – это переводчик, программа которая преобразует другие программы в машинный код. Этот процесс так и называется – компиляция кода.
Процессор состоит из триллионов транзисторов. Как не парадоксально, чтобы управлять этими атомами логики компьютера хватает двух чисел: 0 и 1. От последовательности бинарного потока и зависит, что за последовательность операций будет выполнять CPU. Человеку сложно сразу готовить набор команд в формате бесконечной комбинации нолей и единиц. Намного проще свести алгоритм к последовательности команд языка программирования, а рутинное преобразование по примитивным правилам поручить компилятору.
Машинный кодКомпилятор – это отдельная утилита. Не так давно программисты и код набирали в стандартном текстовом редакторе. Но вскоре стало ясно: лучше объединить средства и инструменты в один продукт. Так появилось понятие среды разработки – IDE или, другими словами, комплексного набора:
Какой компилятор для кода на C и C++ подойдет, зависит от сценария применения. Помимо отдельного решения и среды разработки есть также онлайн-компиляторы. Такое разнообразие оправдано.
Изолированная утилита отличается от IDE тем, что не вынуждает пользоваться сопутствующими модулями. Пользователь волен, например, выбрать для себя текстовой редактор или отладчик. Полная свобода без ограничений: можно задействовать любые варианты, предлагаемые рынком программного обеспечения. Однако большие проекты сложно вести, вооружившись разнородным софтом.
Эту задачу решает IDE. Интегрированная среда разработки, предлагает уже готовый набор инструментов, о совместимости и согласованной работе которых заранее позаботился разработчик. Такие системы универсальны, но каждая конкретная, тем не менее, тяготеет к некоторой области применения.
Есть продукты простотой интерфейса и эксплуатации, больше подходящие начинающим, другие – насыщены множеством полезных функций, третьи – включают дополнительные библиотеки шаблонов, четвертые – помогают запустить эмуляцию процессора, поддерживающего вычисления с плавающей запятой и так далее.
Наконец, онлайн-компиляторы годятся для создания не слишком сложных программ и отличаются кроссплатформенностью. Легко открыть веб браузер и зайти на страницу сервиса.
Такие веб-ориентированные решения легко использовать в командной работе. Можно создавать проект одновременно нескольким программистам, подключаясь к конкретной рабочей площадке удаленно.
Таким образом, выбирать компилятор стоит, отталкиваясь от специфики задач и формата работы.
За время существования и развития этих языков программирования появилось немало связанных продуктов: от текстовых редакторов с подсветкой кода и быстрых компиляторов, до интегрированных сред разработки с невероятными возможностями. Выбрать лучшие компиляторы C и C++ из такого разнообразия крайне сложно. Ниже представлены самые успешные бесплатные проекты. Эти продукты поддерживают одновременно более одной платформы, используются миллионами программистов и продолжают развиваться усилиями крупнейших комьюнити.
VS Code изначально текстовой редактор кода, доступный для операционных систем Windows, macOS и Linux. Компилятор устанавливается как плагин. Таким же образом можно интегрировать и другие функции, превратив приложение в полноценную IDE.
Эмблема и интерфейс VS CodeБазовые достоинства:
Дополнительные опции: подсветка синтаксиса и автодополнение кода. Самый же практичный бонус – система IntelliSense, которая облегчает поиск и устранение ошибок, обеспечивает связь с API и помогает обогащать код объектами из файлов, не связанных с проектом напрямую.
VS Code – выдающийся инструмент, аккумулирующий все разнообразие современных технологий программирования в одном продукте.
Наверное, самая распространенная IDE для разработчиков на языках C и C++.
Так выглядит рабочее окно Dev-C++Используется в индустрии с 1998 года и остается востребованной до сих пор. Специалисты и начинающие особенно ценят эту среду за ряд уникальных свойств:
Единственный ощутимый недостаток – IDE поддерживает только операционные системы Microsoft. Однако и это ограничение можно обойти, если использовать эмуляторы.
Это интегрированная среда обработки выделяется поддержкой самых актуальных языков программирования: содержит компиляторы C# (си шарп), а также Python и Node.js.
Интерфейс Microsoft Visual C++К услугам пользователя:
Для поиска ошибок, автодополнения и других повышающих эффективность работы возможностей применяется IntelliSense.
Программа не просто популярна, но поддерживается гигантским комьюнити. Значит решать любые вопросы по эксплуатации и получить поддержку на этой платформе проще, чем на других.
Этот компилятор будет интересен тем, в чьих компьютерах работают процессоры одноименной корпорации.
Вид рабочей области компилятора Intel C++Продукт оптимизирован под аппаратные решения Intel. Благодаря использованию SIMD-инструкций и всеобъемлющей системы кэширования утилита компилирует с увеличенной скоростью на родной платформе. При этом производительность сохраняется даже в точках, которые вызывают проседание в работе конкурирующих решений.
Этот компилятор C/C++ демонстрирует рекордную результативность на процессорах AMD и предлагает расширенные возможности по исправлению ошибок.
Продукт поддерживает межъязыковые вызовы, работая и с Fortran. Приложение имеет версии дистрибутива для всех самых популярных операционных систем.
Это не программа, а сервис компилятор. Плюс в том, что устанавливать приложение не нужно. Достаточно открыть браузер и проверить как конкретный код собирается и работает. Доступны разные версии компилирования, например, MIPS GCC, GCC-5, Clang и другие. Допускается одновременно запускать более одного компилятора и использовать два и более источников. Это сильно помогает при оптимизации сборки.
Так выглядит Compiler Explorer, запущенный в Mozilla FirefoxКроме того, сервис ищет ошибки, позволяет выбрать формат отображения кода и сопоставить интересующие участки исходника с соответствующими местами в полученном ассемблере.
Пользоваться Compiler Explorer не трудно, а производительность поражает. Компиляция идет сразу при наборе – это мгновенная обратная связь.
Продукт больше напоминает IDE и выглядит ярко на фоне других онлайн-решений. Подкупает также поддержка многих других языков программирования.
Еще один онлайн-сервис с букетом полезных опций и полной совместимостью с новейшей версией C++17. Поддерживается многофайловость, настраиваются привязки клавиш редактора, предусмотрена поддержка версий: Clang, GCC, ZAPCC и других.
Сервис Wandbox в браузере ChromiumОтдельное преимущество – подключение дополнительных библиотек кроме стандартной: Boost, MassagePack, Sprout и других.
Программы, после компиляции запускаются в песочнице, которая также предлагает ввод и вывод файлов.
Сервис адекватен для быстрой компиляции кода и будет полезен как тестовая площадка.
Хотя текстовый редактор не подсвечивает синтаксис и не ищет ошибки, Wandbox подкупает простотой. Чтобы выполнять работу используя сервис даже не нужна регистрация.
Нельзя не сказать и о поддержке других языков. Это и популярные Java, Python, Ruby, Perl, Swift, и нишевые Pascal, Lisp и другие.
На этом можно поставить точку. Описанные компиляторы и IDE – выбор миллионов программистов и студентов создающих код на C и C++. Чтобы подобрать тот самый продукт и пользоваться бесплатно не лишним будет попробовать каждый.
Практика – лучший способ найти оптимальное решение для конкретных задач. Список лучших компиляторов намного шире. Доступна масса других решений: платных или предназначенных только для одной платформы. Здесь приведены самые известные и универсальные.
Visual Studio Code
1
Microsoft Visual C++ Community Version
1
Intel C++
1
Dev-C++
AMD x86 Open64 Compiler Suite
C++ Compiler Explorer
Wandbox
ВикиЧтение
Язык Си — руководство для начинающих
Прата Стивен
Содержание
Компиляция программ, состоящих из двух или более функций
Простейший способ использования нескольких функций в одной программе заключается в том, чтобы поместить их в один файл, после чего осуществить компиляцию программы, содержащейся в этом файле так, как будто она состояла из одной функции.
Второй способ заключается и применении директивы #include. Если одна функция содержится в файле с именем file1.с, а вторая и файле file2.c, поместите эту директиву в файл filel.c:
#include «file2.c»
Дополнительная информация о директиве #include находится в гл. 11. Другие возможные способы являются в большей степени системнозависимыми. Вот некоторые из них:
Компиляция Процедура создания большинства приложений является общей и приведена на рис. 2.2. Рис. 2.2. Схема компиляции программыПервой фазой является стадия компиляции, когда файлы с исходными текстами программы, включая файлы заголовков, обрабатываются компилятором
Компиляция ядра После того как вы сконфигурировали ядро системы, выполнив make xconfig или другую команду, приведенную в начале данной главы, вы должны скомпилировать ядро и установить его модули. Для этого необходимо выполнить следующие команды:# make dep# make bzImage# make modules# make
20.5. Компиляция ядра 20.5.1. Зачем обновлять ядро? Linux развивается быстрее любой другой операционной системы. Регулярно появляются новые версии ядра, реализующие новые функции. Например, едва успел выйти дистрибутив Fedora Core 4 на ядре 2.
28.2. Компиляция модуля Компилировать мы будем файл module.c. Для этого понадобится установленный компилятор gcc, заголовочные файлы и исходные тексты ядра. Если вы дочитали книгу до этой главы, то у вас уже должны быть установлены пакеты:1. cpp — препроцессор cpp;2. binutils — набор
3.4.3. Компиляция Как правило, исходные коды программ распространяются в виде архива с «двойным расширением» -.tar.gz. Исходный код принято распаковывать в каталог /usr/src. Поэтому для распаковки архива вам нужно выполнить следующие команды:sucd /usr/srcgunzip архив.tar.gztar xvf
Компиляция программ Даже после появления пакетов, которые представляли собой уже скомпилированные программы, компиляция долгое время оставалась и для некоторых остается основным средством установки. Примечание Первые прекомпилированные наборы появились в
Создание более сложных программ Создавать VBA-программы, добавляющие функциональные возможности существующим приложениям, может каждый, кто способен запомнить свое школьное расписание или прочитать за завтраком инструкцию на упаковке с вермишелью быстрого
Совет 46. Передавайте алгоритмам объекты функций вместо функций Часто говорят, что повышение уровня абстракции языков высокого уровня приводит к снижению эффективности сгенерированного кода. Александр Степанов, изобретатель STL, однажды разработал небольшой комплекс
Почему компиляция? Читатели, пользовавшиеся языком Бейсик, могут удивиться, зачем столько шагов для того, чтобы выполнить программу. Кажется, что такой способ компиляции требует больше времени (и в некоторых случаях это может быть действительно так). Но, поскольку в
4.4.7. Взаимоблокировки двух и более потоков Взаимоблокировка происходит, когда два (или более) потока блокируются в ожидании события, наступление которого на самом деле зависит от действий одного из заблокированных потоков. Например, если поток A ожидает изменения
Условная компиляция В этом разделе описываются директивы, которые управляют условной компиляцией. Эти директивы позволяют исключить из процесса компиляции какие-либо части исходного файла посредством проверки условий (константных
12. 3.5. Адаптеры функций для объектов-функций В стандартной библиотеке имеется также ряд адаптеров функций, предназначенных для специализации и расширения как унарных, так и бинарных объектов-функций. Адаптеры – это специальные классы, разбитые на следующие две
1.1.2 Компиляция Откуда появились выходной поток cout и код, реализующий операцию вывода ««? Для получения выполняемого кода написанная на С++ программа должна быть скомпилирована. По своей сути процесс компиляции такой же, как и для С, и в нем участвует большая часть входящих
19.11.2. Вызов функций из файла функций Мы уже рассматривали, каким образом функции вызываются из командной строки. Эти типы функций обычно используются утилитами, создающими системные сообщения.А теперь воспользуемся снова описанной выше функцией, но в этом случае
C — это язык среднего уровня, и ему нужен компилятор для преобразования его в исполняемый код, чтобы программу можно было запустить на нашей машине.
Как скомпилировать и запустить программу на C?
Ниже приведены шаги, которые мы используем на машине Ubuntu с компилятором gcc.
$ vi имя_файла.c
$ gcc -Wall имя_файла.c –o имя_файла
$ ./filename
Что происходит внутри процесса компиляции?
Компилятор преобразует программу C в исполняемый файл. Существует четыре этапа превращения программы C в исполняемый файл:
Выполняя приведенную ниже команду, мы получаем все промежуточные файлы в текущем каталоге вместе с исполняемым файлом. .
$gcc -Wall -save-temps имя_файла.c –o имя_файла
На следующем снимке экрана показаны все сгенерированные промежуточные файлы.
Давайте последовательно посмотрим, что содержат эти промежуточные файлы.
Предварительная обработка
Это первая фаза, через которую проходит исходный код. Этот этап включает:
Предварительно обработанный вывод сохраняется в файле имя_файла.i . Давайте посмотрим, что находится внутри filename.i: using $vi filename.i
В приведенном выше выводе исходный файл заполнен большим количеством информации, но в конце наш код сохраняется.
Анализ:
Компиляция
Следующим шагом является компиляция filename.i и создание файла; промежуточный скомпилированный выходной файл filename.s . Этот файл находится в инструкциях уровня сборки. Давайте посмотрим на этот файл, используя $vi filename.s
Снимок показывает, что он написан на языке ассемблера, который ассемблер понимает.
Сборка
На этом этапе имя файла.s берется в качестве входных данных и преобразуется ассемблером в имя_файла.o . Этот файл содержит инструкции машинного уровня. На этом этапе только существующий код преобразуется в машинный язык, вызовы функций, таких как printf(), не разрешаются. Давайте просмотрим этот файл, используя $vi filename.o
Связывание
Это заключительный этап, на котором выполняются все связывания вызовов функций с их определениями. Линкер знает, где реализованы все эти функции. Компоновщик также выполняет некоторую дополнительную работу, он добавляет в нашу программу дополнительный код, который требуется при запуске и завершении программы. Например, есть код, необходимый для настройки среды, такой как передача аргументов командной строки. Эту задачу легко проверить с помощью $размер имени файла.o и $размер имени файла . С помощью этих команд мы знаем, как выходной файл увеличивается от объектного файла до исполняемого файла. Это связано с дополнительным кодом, который компоновщик добавляет в нашу программу.
Обратите внимание, что GCC по умолчанию выполняет динамическую компоновку, поэтому printf() динамически компонуется в приведенной выше программе. Обратитесь к этому, этому и этому для получения более подробной информации о статических и динамических ссылках.
Эта статья предоставлена Викашем Кумаром . Пожалуйста, пишите комментарии, если вы обнаружите что-то неправильное, или вы хотите поделиться дополнительной информацией по теме, обсуждаемой выше.
Для тех из нас, кто имеет опыт написания программ на C, gcc
, вероятно, знакомая команда. Быстрая команда gcc
превратит файл C (указанный с окончанием .c
) в исполняемый файл, который можно использовать для запуска нужной программы. Тем не менее, что происходит за кулисами, между теми шагами, когда gcc
берет файл и волшебным образом превращает его в исполняемую программу, как трюк Гоба Блута?
Язык программирования C называется компилируемым языком. Другими словами, программы на C реализуются компиляторами, которые переводят исходный код в машиночитаемый код (подробнее об этом позже).
Коллекция компиляторов GNU (GCC) является одним из таких компиляторов для языка C. Все верно, этот сбивающий с толку, невероятный, величественный, взрослый яйцевидный бык представляет собой мощную программу, которая может превратить необработанный код C в простые в использовании исполняемые файлы. На самом деле C — лишь один из нескольких языков, поддерживаемых GCC, включая C++, Fortran и Go. Сегодня GCC является стандартным компилятором для многих Unix-подобных систем, включая Linux.
Компиляторы транслируют исходный код в четыре этапа — предварительная обработка, компиляция, сборка и компоновка. Давайте разберем каждый шаг по очереди. По мере продвижения мы будем использовать пример программы main.c
, которая, как мы видим, представляет собой простую программу на C, которая печатает сообщение, определенное в макропеременной:
Препроцессор сначала читает исходный код и подготавливает его к компиляции через три задачи. Сначала препроцессор удаляет из кода все комментарии, те строки, которые указаны в C на /* */
или //
. Во-вторых, препроцессор будет включать любые файлы заголовков, связанные в начале файлов C с помощью синтаксиса #include "example_header.h"
. Наконец, все макропеременные, определенные в файле, заменяются их указанными значениями.
Мы можем просмотреть результаты препроцессора, запустив gcc
с опцией -E
, которая подавляет процесс компиляции после этого первого шага:
Здесь мы видим, что препроцессор удалил main.c
своих комментариев при замене макропеременной MESSAGE ее определенным значением.
После предварительной обработки вновь отфильтрованный файл передается компилятору. Компилятор берет предварительно обработанный файл и использует его для генерации соответствующего ассемблерного кода. Ассемблерный код или язык ассемблера (часто сокращенно asm) — это язык программирования высокого уровня, который сопоставляет код программирования с инструкциями машинного кода данной архитектуры. Не стесняйтесь узнать больше о деталях ассемблерного кода здесь.
Чтобы остановить процесс компиляции на этом втором этапе, мы можем запустить файл нашего примера main.c
с параметром gcc
-c
. Затем мы можем просмотреть получившуюся, по большей части нечитаемую мешанину ассемблерного кода:
От компилятора новый ассемблерный код передается ассемблеру. Ассемблер делает именно то, что следует из его названия — он ассемблирует код в объектный код. Там, где ассемблерный код представляет собой соответствие между программой и машинным кодом, объектный код представляет собой чистый машинный код (то есть двоичный). Вы можете найти больше информации об объектном коде здесь.
Ассемблерный код нашего файла main.c
не был достаточно нечитаемым для меня. Запустим gcc
с опцией -S
для остановки компилятора на этапе сборки:
Ну хоть форматирование покрасивше?
Предварительно обработанный, скомпилированный и собранный теперь объектный код наконец готов для преобразования в исполняемый файл. Для этого компилятор делает последний шаг и отправляет код компоновщику, который берет все переданные ему объектные коды и библиотеки и связывает их вместе в один исполняемый файл.
В рамках нашего примера main.c
компилируется без каких-либо дополнительных ссылок или файлов, поэтому программа сама будет преобразована в исполняемый файл. Увы, для финала давайте запустим полный шебанг (здесь не подразумевается ссылка на вычисления), gcc main.c
без каких-либо опций, для предварительной обработки, компиляции, сборки и компоновки программы одновременно.
… что случилось?
Без указания имени исполняемого файла (что можно сделать с помощью -o
), по умолчанию GCC сохраняет успешно скомпилированный исполняемый файл в файле с именем a.out
. Чтобы запустить нашу программу, мы будем использовать команду ./a.out
, которая запускает исполняемый файл в текущем рабочем каталоге:
И вуаля! [Вставьте здесь кричащую в ужасе Шелли Дюваль.]
Ссылки:
en.wikipedia.org
en.