Расширение макроса препроцессора до другой директивы препроцессора

StackOverflow https://stackoverflow.com/questions/1262063

Вопрос

Сначала я думал, что мне это нужно, но в конце концов избежал этого.Однако мое любопытство (и тяга к знаниям, хм) заставляют меня спросить:

Может ли макрос препроцессора, например, в

#include "MyClass.h"

INSTANTIATE_FOO_TEMPLATE_CLASS(MyClass)

разверните до другого включения, как в

#include "MyClass.h"

#include "FooTemplate.h"
template class FooTemplate<MyClass>;

?

Это было полезно?

Решение

Я считаю, что это невозможно сделать, это потому, что препроцессор одиночный проход.Таким образом, он не может выдавать другие директивы препроцессора.

В частности, из Стандарта C99 (пункт 3 6.10.3.4).:

3 Полученный полностью замененный макросом токен предварительной обработки последовательность не обрабатывается как директива предварительной обработки, даже если она похожа на нее, ...

Достаточно интересно, что именно поэтому унарный _Pragma оператор был добавлен в c99.Потому что #pragma не может быть выдан макросами, но _Pragma могу.

Другие советы

Стандарт C говорит это о директивах предварительной обработки (C99 - 6.10 (2) - Директивы предварительной обработки):

Директива предварительной обработки состоит из последовательности токенов предварительной обработки, которая начинается с токена # предварительной обработки, который (в начале фазы перевода 4) ...

и (C99 - 6.10(7)):

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

ПРИМЕР В:

#define EMPTY
EMPTY # include <file.h>

последовательность токенов предварительной обработки во второй строке не является директивой предварительной обработки, поскольку она не начинается с # в начале фазы перевода 4, даже если она будет делать это после замены ПУСТОГО макроса

Итак, нет, макросы не могут расширяться в '#include'директива предварительной обработки.Эти директивы должны быть на месте в начале этапа перевода 4 (когда происходит обработка этих директив, происходит предварительная обработка).Поскольку расширение макросов происходит во время фазы 4, макросы не могут вызвать существование чего-либо в начале фазы 4.

Однако я хотел бы отметить, что следующее делает работа:

#ifdef WIN32
#define PLATFORM_HEADER "platform/windows/platform.h"
#else
#define PLATFORM_HEADER "platform/linux/platform.h"

#include PLATFORM_HEADER

потому что стандарт C гласит это (C99, 6.10.2 (4) - включение исходного файла):

Директива предварительной обработки вида

# include pp-tokens new-line

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

Все директивы препроцессора интерпретируются до начала расширения макроса, поэтому нет, вы не можете расширить макрос в директиву #include и интерпретировать его как таковой.Вместо этого он будет интерпретирован как (ошибочный) код C++.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top