Spec-Zone.ru › GCC 5 CPP

2.6 Вычисленные включения

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

#if SYSTEM_1
# include "system_1.h"
#elif SYSTEM_2
# include "system_2.h"
#elif SYSTEM_3
…
#endif

что быстро становится утомительным. Вместо этого препроцессор предоставляет возможность использования макроса для имени заголовочного файла. Это называется вычисленным включением. Вместо того, чтобы писать имя заголовочного файла как непосредственный аргумент ‘#include’, вы просто ставите имя макроса:

#define SYSTEM_H "system_1.h"
…
#include SYSTEM_H

SYSTEM_H будет расширен, и препроцессор будет искать system_1.h, как если бы ‘#include’ было написано таким образом изначально. SYSTEM_H может быть определён вашим Makefile с опцией -D.

Вы должны быть осторожны при определении макроса. ‘#define’ сохраняет токены, а не текст. Препроцессор не знает, что макрос будет использоваться как аргумент ‘#include’, поэтому он генерирует обычные токены, а не имя заголовочного файла. Это вряд ли вызовет проблемы, если вы используете включения в двойных кавычках, которые достаточно близки к строковым константам. Однако, если вы используете угловые скобки, у вас могут возникнуть проблемы.

Синтаксис вычисленного включения на самом деле немного более общий, чем указанный выше. Если первый символ, не являющийся пробелом, после ‘#include’, не ‘"’ или ‘<’, то вся строка макро-расширяется, как если бы это был обычный текст.

Если строка расширяется до единственной строковой константы, содержимое этой строковой константы является файлом, подлежащим включению. CPP не перепроверяет строку на встроенные кавычки, но также не обрабатывает обратные косые черты в строке. Следовательно

#define HEADER "a\"b"
#include HEADER

ищет файл с именем a\"b. CPP ищет файл в соответствии с правилами для включений в двойных кавычках.

Если строка расширяется до потока токенов, начинающегося с токена ‘<’ и содержащего токен ‘>’, то токены между ‘<’ и первым ‘>’ объединяются для формирования имени файла, подлежащего включению. Любые пробелы между токенами сокращаются до одного пробела; затем любой пробел после начального ‘<’ сохраняется, но конечный пробел перед закрывающим ‘>’ игнорируется. CPP ищет файл в соответствии с правилами включения в угловых скобках.

В любом случае, если в строке есть какие-либо токены после имени файла, возникает ошибка, и директива не обрабатывается. Также возникает ошибка, если результат расширения не соответствует ни одному из двух ожидаемых форматов.

Эти правила являются реализационно-зависимым поведением в соответствии со стандартом C. Чтобы свести к минимуму риск различного толкования ваших вычисленных включений различными компиляторами, мы рекомендуем использовать только один макрос типа объект, который расширяется до строковой константы. Это также позволит снизить путаницу для людей, читающих вашу программу.

Далее: Заголовочные файлы-оболочки, Предыдущее: Альтернативы заголовочным файлам-оболочкам #ifndef, Вверх: Заголовочные файлы [Содержание][Индекс]

© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-5.5.0/cpp/Computed-Includes.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API