Spec-Zone.ru › GCC 12 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-12.1.0/cpp/Computed-Includes.html

Spec-Zone.ru

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