- •3.В тексте распознаются директивы и лексемы препроцессора, а каждый комментарий заменяется одним символом
- •ESC-последовательности – специальные символьные комбинации, которые представляют пробельные символы и неграфические символы в
- •Препроцессорные лексемы или лексемы препроцессора - символьные константы, имена включаемых файлов, идентификаторы, знаки
- •Директивы препроцессора обычно помещаются в начало исходного кода, но допустимы в любой точке
- •Состояние определенности и неопределенности является важным свойством идентификатора, независимо от его фактического определения.
- •!!! директива препроцессора не должна заканчиваться точкой с запятой (;). Любые символы, найденные
- •Вызов макроса приводит к двум типам замены:
- •Пример:
- •Сравните CUBE и cube:
- •Условная компиляция - исходный файл можно компили- ровать не целиком, а частями, используя
- •Макроопределения могут изменяться при различных действиях компиляции по неким причинам.
- •Можно - один и тот же исходный файл скомпилировать в две разные программы
- •!!! все знаки являются важными, за исключением пробелов, расположенных в начале и в
- •часть-группы:
- •управляющая-строка:
Макроопределения могут изменяться при различных действиях компиляции по неким причинам.
Некие макросы являются заблаговременно определенными,
(в зависимости от типа компьютера |
- имя 'vax‘ на |
компьютерах Vax, а на остальных |
компьютерах оно |
не определено. |
|
Часть макросов def системными подключаемыми файлами и на разных системах и компьютерах определяются
различные макросы с |
различными значениями. |
Полезно проверять эти |
макросы условными |
конструкциями во избежание использования аппаратных возможностей на компьютере, где они не реализованы.
В результате макросы являются обычным методом настройки программы для разных систем либо приложений. К примеру, можно употреблять макрос 'BUFSIZE' в условии препроцессора для генерации кода, зависящего от выбранной конфигурации.
Макросы могут определяться либо уничтожаться с помощью
Можно - один и тот же исходный файл скомпилировать в две разные программы методом определения подходящего макроса, использования условий для проверки его значения и передачи этого значения макроса через опции компилятора.
макросы могут указывать на архитектуру модели компьютера, отдельную модель компьютера, на ОС, её версию либо на специальные возможности конфигурации, причем можно все в одном макросе.
Некоторые компиляторы - утверждения - более систематическую альтернативу макросам при разработке условий на проверку типа компьютера
либо системы, используемой |
при компиляции |
программы. Утверждения |
обычно определены |
заранее, хотя они могут быть также определены директивами препроцессора либо с помощью опций. В отличие от макросов, утверждения состоят из верно поставленного вопроса и твета на него:
!!! все знаки являются важными, за исключением пробелов, расположенных в начале и в конце ANSWER. Различия в пробелах в середине значения игнорируются. Нельзя употреблять знаки ')' и '(' в значении ANSWER.
#if #PREDICATE (ANSWER) - пример проверки, явля- ется ли ответ ANSWER утверждением PREDICATE
Для одного утверждения может существовать несколько ответов. Если ответ пропущен, то следует проверять, существует ли он вообще:
#if #PREDICATE
Большая часть утверждений определены заранее Пример: в GNU C++ 3 таких утверждения: 'system' - тип ОС,
'cpu' - описание архитектуры компьютера 'machine' - дополнительная информацию о компьютере.
Многие Unix С++ компиляторы предоставляют лишь один ответ на утверждение 'system': #system (unix)
Можно создавать свои утверждения (директива #assert):
Удалить утверждение - директива #unassert. такой же синтаксис как и #assert. Удалить все утверждения для PREDICATE: #unassert PREDICATE
Есть возможность добавления либо удаления утверждений с помощью опций компилятора.
Сообщения об ошибках и предупреждениях
#error - вынуждает препроцессор сделать отчет о фатальной ошибке. Все что следует после '#error' употребляется для сообщения. В теле условия, проверяющего комбинацию характеристик, не до конца поддерживаемых программой, она употребляется для сообщения о вероятной ошибке – есть во всех версиях С++
#warning – аналогично #error, но предупреждение. Ее можно употреблять в устаревших подключаемых файлах с указанием на новенькую версию файла.
Изменения во включаемых файлах
#line – можно указать номер строчки настоящего исход-
ного файла совместно с его именованием (3 способа):
#line LINENUM "FILENAME" - тут LINENUM это десятичная целая константа, а FILENAME - строковая константа, указывающая, что следую-щая строчка является строчкой исходного файла с именованием FILENAME, а её номер - LINENUM. двойные кавычки для FILENAME обязательны.
#line ANYTHING ELSE - значение ANYTHING ELSE проверяется на наличие макро вызовов, которыепотом подставляются. Результ - десятичная целая константа, за которой может следовать стороковая константа.
Пустая директива
# - Использование этой директивы не вызывает никаких действий.
Выдача дополнительных указаний компилятору #pragma различные конкретные возможности у разных компиляторов
Основные версии C++ поддерживают директивы :
- #pragma argsused - допустима лишь между
- #pragma exit имя-ф-ии [приоритет] |
задает ф-ию |
-#pragma startup имя-ф-и [приоритет] |
(ф-ии), |
которые вызываются при загрузке программы (перед вызовам main), или при перед выходом из программы через _exit. Заданное имя-ф-ии обязано относиться к ранее объявленной ф-и, не принимающей аргументов и возвращающей значение void, т.е. void func(void); и ее надо объявить перед #pragma. Приоритет - целое число от 64 до 255, старший - 0 (от 0 до 63 употребляются библиотеками языка) и не используются. По умолчанию задано 100.
-#pragma inline –сообщает компилятору, что програм-ма содержит интегрированные ассемблерные коды
-#pragma option [опции] - включения опций компи- лятора командной строчки в код вашей программы
-#pragma saveregs - при входе в ф-ю huge значения всех регистров останутся без изменения. Исполь-зуется перед ф- ей (обычно asm), действует только на эту ф-ю.
-#pragma hdrfile "FILENAME" - def имя файла, в котором
-#pragma hdrstop - задает конец списка файлов для прекомпиляции
-#pragma warn – переопределять конкретные предупреждения в опциях компилятора
#pragma warn +xxx выдача предупреждения xxx
будет разрешена в случае #pragma warn -yyy выдача предупреждения yyy
будетзапрещена в случае #pragma warn.zzz статус выдачи сообщения zzz будет восстановлен в то состояние, которое было к моменту начала компиляции файла.
#pragma intrinsic function – включает ф-ю как inline в файл программы
Синтаксис директив препроцессора C++ файл-для-препроцессора:
группа
группа:
часть группы
часть-группы:
<лексемы-препроцессора> новая-строка if-раздел
управляющая строка if-раздел:
if-группа <elif-группы> <else-группа> endif-строка if-группа:
#if выражение-типа-константы новая-строка <группа>
#ifdef идентификатор новая-строка <группа> #ifndef идентификатор новая-строка <группа>
elif-группы: elif-группа
elif-группы elif-группа elif-группа:
#elif выражение-типа-константы <группа> else-группа:
#else новая-строка <группа> endif-строка:
управляющая-строка:
#include лексемы-препроцессора новая-строка #define идентификатор список-замены новая-строка
#define идентификатор левая-круглая-скобка <список-идентификаторов>) список-замены новая-строка
#undef идентификатор новая-строка
#line <лексемы-препроцессора> новая-строка #pragma <лексемы-препроцессора> новая-строка #pragma warn действие сокращение новая-строка
#pragma inline новая-строка ? новая-строка
действие: одно из + - .
сокращение:
amb amp apt aus big cin cpt def dup elf mod par pia pro rch ret rng rpt rvf sig str stu stv sus ucp use vol zst левая-круглая-скобка:
символ левой круглой скобки без предшествующих
пробельных символов
список-замены: <лексемы-препроцессора>
лексемы-препроцессора:
имя-заголовка (только для директивы #include) идентификатор (без различения ключевого слова) константа строковый-литерал операция пунктуатор
любой не-пробельный символ, не относящийся к предыдущим пунктам имя-заголовка:
<последовательность-символов-заголовка> последовательность-символов-заголовка:
символ-заголовка последовательность-символов-заголовка символ-
заголовка символ-заголовка:
любой символ из исходного множества символов,