Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [FAQ] Что такое компилятор... Препроцессор, компилятор, компоновщик... 
:(
    Опции темы
bsa
Дата 25.8.2009, 13:00 (ссылка) |    (голосов:11) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



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

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

Препроцессинг выполняется препроцессором. На этой стадии обрабатываются директивы препроцессора, которые в коде можно отличить по символу "решетка":
Выделить всёкод C++
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
#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 удаление:
Выделить всёБез подсветки
1:
gcc -DMY_MACRO="(x*x)" -UWIN32 ...
Эта комадна создаст макроопределение указанное выше, а так же отменит определение WIN32 (т.е. /* some code */ скомпилирован не будет). Все известные препроцессоры имеют ряд предопределенных заранее макросов. Обычно, они начинаются с двух символов "подчеркивание". Например: __cplusplus определен всегда, когда компиляция ведется с языка С++; WIN32 определен, когда целевая платформа Microsoft Windows; есть еще unix и linux... Полный список можно найти через поисковые машины (лучше глобальные, а не русскоязычные) по запросу "<компилятор> preprocessor defines" (без кавычек).

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

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

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

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

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

Назад к FAQ

Это сообщение отредактировал(а) bsa - 26.7.2011, 11:07
PM   Вверх
Galaran
Дата 25.8.2009, 20:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 91
Регистрация: 25.5.2009

Репутация: нет
Всего: 2



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


Вопрос - как я понял, такие версионные макросы определяются стандартным
Выделить всёкод C++
1:
#define WIN32


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


PM MAIL   Вверх
bsa
Дата 26.8.2009, 16:56 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Galaran, добавил ответы в статью. Спасибо.
PM   Вверх
serghd
Дата 2.1.2011, 04:08 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 5.10.2009

Репутация: нет
Всего: нет



bsa, не добавил главную ide - NetBeans
PM MAIL   Вверх
bsa
Дата 5.1.2011, 20:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



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

Не добавил потому, что она сложна в настройке под Windows. А новички, обычно, под ней и работают.
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0780 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.