
-
Глава 4. Препроцессор и особенности компилятора
-
Директивы препроцессора
-
Макроопределения
-
Директива #include
-
Условная компиляция
-
Директива #еггог
-
Директива #line
-
Директива #pragma
-
Типичное применение препроцессорных директив
-
-
Особенности C++Builder
-
Расширения языка С
-
-
Управление компилятором
-
Страница Compiler
-
Страница Advanced Compiler
-
Страница Directories/Conditionals
-
-
Глава 4. Препроцессор и особенности компилятора
Чтобы закончить наш, так сказать, пропедевтический курс по языку С, нам нужно еще рассказать о препроцессоре; и о некоторых ключевых словах C++Builder, которые не укладываются в стандарт ANSI. Кроме того, мы расскажем о диалоге Project | Options, в котором задаются различные параметры, управляющие компиляцией программы.
Директивы препроцессора
Препроцессорная обработка представляет собой первую фазу того процесса, что именуется компиляцией программы на C/C++. Компилятор C++Builder не генерирует промежуточного файла после препроцессорной обработки. Однако, если хотите, можно посмотреть на результат работы препроцессора, запустив отдельную программу срр32.ехе из командной строки:
срр32 myfile.c
Макроопределения
Макроопределения, называемые в просторечии макросами, определяются директивой препроцессора #define. Можно выделить три формы макросов #define:
-
простое определение символа
-
определение символической константы
-
определение макроса с параметрами.
Простое определение выглядит так:
#define NDEBUG
После такой директивы символ NDEBUG считается определенным. Не предполагается, что он что-то означает; он просто — определен (как пустой). Можно было бы написать:
#define NDEBUG 1
Тогда NDEBUG можно было бы использовать и в качестве символической константы, о которых говорилось в предыдущей главе. Всякое вхождение в текст лексемы NDEBUG препроцессор заменил бы на единицу. Зачем нужны макроопределения, которые ничего не определяют, выяснится при обсуждении условных конструкций препроцессора.
Как вы могли бы догадаться, #define может определять не только константы. Поскольку препроцессор выполняет просто текстовую подстановку, можно сопоставить символу и любую последовательность операторов, как показано ниже:
#define SHUTDOWN \
printf("Error!"); \ return -1
…
If (ErrorCondition()) shutdown; // "Вызов" макроса.
Обратная дробная черта (\) означает, что макрос продолжается на следующей строчке. В отличие от операторов С директивы препроцессора должны располагаться в одной строке, и поскольку это технически не всегда возможно, приходится явно вводить некоторый признак продолжения.
Определенный ранее макрос можно аннулировать директивой #undef:
#undef NDEBUG
После этого макрос становится неопределенным, и последующие ссылки на него будут приводить к ошибке при компиляции.
Предопределенные макросы
Компилятор C++Builder автоматически определяет некоторые макросы. Их можно разбить на две категории: макросы ANSI и макросы, специфические для C++Builder. Сводки предопределенных макросов даны соответственно в таблицах 4.1 и 4.2.
Таблица 4.1. Предопределенные макросы ANSI
Макрос |
Описание |
DATE |
Литеральная строка в формате “mmm dd yyyy”, представляющая дату обработки данного файла препроцессором. |
FILE |
Строка имени текущего файла (в кавычках). |
LIME |
Целое, представляющее номер строки текущего файла. |
STDC |
Равно 1, если установлена совместимость компилятора со стандартом ANSI (ключ -А командной строки). В противном случае макрос не определен. |
TIME |
Строка в формате “hh:mm:ss”, представляющее время препроцессорной обработки файла. |
Значения
макросов _file_ и _line_ могут быть изменены
директивой #line (см. далее).
Таблица 4.2. Предопределенные макросы C++Builder
Макрос |
Значение |
Описание |
ВСОРТ |
1 |
Определен в любом оптимизирующем компиляторе. |
BCPLUSPLUS |
0х0540 |
Определен, если компиляция производится в режиме C++. В последующих версиях будет увеличиваться. |
BORLANDC |
0х0540 |
Номер версии. |
CDECL |
1 |
Определен, если установлено соглашение о вызове cdecl; в противном случае не определен. |
CHARUNSIGNED |
1 |
Определен по умолчанию (показывает, что char по умолчанию есть unsigned char). Можно аннулировать ключом -К. |
CONSOLE |
|
Определен при компиляции консольных приложений. |
CPPUNWIND |
1 |
Разрешение разматывания стека; определен по умолчанию. Для аннулирования можно применить ключ -xd-. |
cplusplus |
1 |
Определен при компиляции в режиме C++. |
DLL |
1 |
Определен, если компилируется динамическая библиотека. |
FLAT |
1 |
Определен при компиляции в 32-битной модели памяти. |
MIХ86 |
|
Определен всегда. Значение по умолчанию — 300. (Можно изменить значение на 400 или 500, применив соответственно ключи /4 или /5 в командной строке.) |
MSDOS |
1 |
Целая константа. |
MT |
1 |
Определен, если установлена опция -WM. Она означает, что будет присоединяться мультили-нейная (multithread) библиотека. |
PASCAL |
1 |
Определен, если установлено соглашение о вызове Pascal. |
TCPLUSPLUS |
0х0540 |
Определен, если компиляция производится в режиме C++ (аналогично bcplusplus ). |
TEMPLATES |
1 |
Определен для файлов C++ (показывает, что поддерживаются шаблоны). |
TLS |
1 |
Thread Local Storage. В C++Builder определен всегда. |
TURBOC |
0х0540 |
Номер версии (аналогичен BORLANDC ). |
WCHART |
1 |
Определен только в программах C++ (показывает, что wear t — внутренне определенный тип. |
WCAR T DEFINED |
1 |
То же, что и WCHAR Т. |
Windows |
|
Определен для кода, используемого только в Windows. |
WIN32 |
1 |
Определен для консольных и GUI-приложений. |
Как видите, многие предопределенные макросы C++Builder отражают те или иные установки параметров компиляции, задаваемые в командной строке (при ручном запуске компилятора Ьсс32.ехе). Те же самые установки могут быть выполнены и в интегрированной среде через диалог Project Options, который мы еще будем рассматривать в этой главе.