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

Spec-Zone.ru

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