Spec-Zone.ru › GCC 13 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. Чтобы свести к минимуму риск различной интерпретации ваших вычисленных включений различными компиляторами, мы рекомендуем вам использовать только один макрос, подобный объекту, который расширяется до строковой константы. Это также минимизирует путаницу для людей, читающих вашу программу.

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

Spec-Zone.ru

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