Spec-Zone.ru › GCC 10 CPP

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

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-10.5.0/cpp/Computed-Includes.html

Spec-Zone.ru

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