Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > [FAQ] Что такое компилятор...


Автор: bsa 25.8.2009, 13:00
Большинство начинающих программистов называют программу, в которой они пишут свои шедевры, словом "компилятор". Это в корне неверно. Данная программа называется "Интегрированная Среда Разработки" (Integrated Development Environment - IDE). Примеры: Microsoft Visual Studio, Borland C++ Builder, DevC++, Eclipse, Qt Creator, KDevelop и другие. Данные программы лишь упрощают работу программиста, объединяя текстовый редактор, редактор форм, компилятор и отладчик в едином интерфейсе. Компиляторы же всегда являются консольными программами (т.е. не имеют графического интерфейса).

Процесс преобразования исходных текстов с языков Си и С++ в готовые исполняемые файлы происходит за 3 этапа:
1. Препроцессинг
2. Компиляция
3. Компоновка

Препроцессинг выполняется препроцессором. На этой стадии обрабатываются директивы препроцессора, которые в коде можно отличить по символу "решетка":
Код
#include <stdio.h>
#define MY_MACRO(x) (x*x)

#if defined (WIN32)
/* some code */
#endif /* defined (WIN32) */

int main()
{
    return MY_MACRO(1+2);
}
При обработке этого кода препроцессор:
1. вместо #include <stdio.h> вставит содержимое этого файла (угловые скобки (<>) означают, что искать его сначала надо в стандартных каталогах, а уж затем в текущем)
2. запомнит, что MY_MACRO определена и ее значение: "(x*x)", где x - первый параметр
3. Проверит, определен ли макрос WIN32, и если не определен, то уберет /* some code */
4. в строке return MY_MACRO(1+2) произведет замену, в итоге получится: return (1+2*1+2) (обратите внимание, что скорее всего получилось не то, что хотел разработчик)
Проверить это можно любым компилятором. Для этого у него есть специальный ключ. Например, у gcc это ключ -E. В итоге команда gcc -E myfile.c выведет на экран результат работы препроцессора, который уже поступит на обработку компилятором...

Через параметры командной строки можно создать необходимый набор макроопределений препроцессора. Это делается ключами -D - добавление и -U удаление:
Код
gcc -DMY_MACRO="(x*x)" -UWIN32 ...
Эта комадна создаст макроопределение указанное выше, а так же отменит определение WIN32 (т.е. /* some code */ скомпилирован не будет). Все известные препроцессоры имеют ряд предопределенных заранее макросов. Обычно, они начинаются с двух символов "подчеркивание". Например: __cplusplus определен всегда, когда компиляция ведется с языка С++; WIN32 определен, когда целевая платформа Microsoft Windows; есть еще unix и linux... Полный список можно найти через поисковые машины (лучше глобальные, а не русскоязычные) по запросу "<компилятор> preprocessor defines" (без кавычек).

По возможности не используйте макроопределения препроцессора в своих программах, так как они могут повлечь за собой очень странные ошибки, не говоря уж о том, что код при этом станет менее читабельным. Если уж без макроопределений никак обойтись нельзя, то сделайте все возможное, чтобы их нельзя было спутать с переменными, функциями и типами.

Компилятор собственно и приводит текст программы к виду, понятному центральному процессору. Результатом его работы является объектный код (на самом деле, этот этап состоит из трех подэтапов: преобразование к промежуточному коду, преобразование к ассемблеру целевого процессора, компиляция с языка ассемблера; но компилятор делает это все сам без дополнительных требований к пользователю). Сам по себе этот код работать не может, так как адреса многих системных и библиотечных  функций ему неизвестны. Чтобы они стали известны используется компоновщик...

Компоновщик (он же "линкер") получает на входе пару списков: библиотек и объектных файлов. Затем он начинает объединять все файлы друг за другом таким образом, чтобы были известны адреса всех функций. Результатом его работы как раз и является, в зависимости от настроек, исполняемый файл или динамическая библиотека.

В большинстве случаев все эти три этапа может выполнить одна и таже программа, которую называют "компилятор". Для этого надо ей указать все исходные файлы и библиотеки, которые нужны будут при компоновке:
Код
gcc -lm -omyprog.exe myfile1.c myfile2.c
Если в указанных файлах код без ошибок, то результатом будет файл myprog.exe, к которому на этапе компоновки будет подключена библиотека libm (стандартная библиотека математических функций, объявленных в <math.h>)

В подавляющем большинстве случаев этап препроцессинга совмещен с компиляцией. Исключениями могут являться случаи, когда необходимо найти причину "странной ошибки", которая может возникнуть из-за неправильного использования макроопределений (например, компилируя какой-то проект, я наткнулся на очень странную ошибку, которой судя по коду в принципе быть не могло; ее причиной оказалось использование переменной с именем "linux"; так как моя основная ОС - GNU/Linux, то компилятор определяет всегда макрос "linux" равный единице, в итоге вместо переменной в код подставлялось число, что и вызывало возмущение компилятора). Так же этими ключами пользуются разработчики IDE для того, чтобы узнать настройки компилятора и сделать подсветку синтаксиса более информативной (Eclipse CDT).

http://forum.vingrad.ru/index.php?show_type=forum&showtopic=269794&kw=faq-c++

Автор: Galaran 25.8.2009, 20:22
Цитата(bsa @  25.8.2009,  13:00 Найти цитируемый пост)
3. Проверит, определен ли макрос WIN32, и если не определен, то уберет /* some code */


Вопрос - как я понял, такие версионные макросы определяются стандартным
Код

#define WIN32


верно ? Где обычно располагаются такие объявления ? Можно ли задать в параметрах препроцессинга ?


Автор: bsa 26.8.2009, 16:56
Galaran, добавил ответы в статью. Спасибо.

Автор: serghd 2.1.2011, 04:08
bsa, не добавил главную ide - NetBeans

Автор: bsa 5.1.2011, 20:46
Цитата(serghd @  2.1.2011,  05:08 Найти цитируемый пост)
bsa, не добавил главную ide - NetBeans 
Цитата(bsa @  25.8.2009,  14:00 Найти цитируемый пост)
и другие

Не добавил потому, что она сложна в настройке под Windows. А новички, обычно, под ней и работают.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)