Как избежать символа # в макросе #define?

Не вдаваясь в детали gory, я хочу использовать макрос #define, который будет расширяться до #include, но знак '#' путает препроцессор (поскольку он считает, что я хочу привести аргумент.)

Например, я хочу сделать что-то вроде этого:

#define MACRO(name) #include "name##foo"

И используйте его таким образом:

MACRO(Test)

который будет расширяться до:

#include "Testfoo"

Смиренный знак # вызывает препроцессор barf. MinGW дает мне следующую ошибку:

'#' is not followed by a macro parameter

Думаю, мне нужно сбегать от знака #, но я этого не сделаю, если это возможно.

Да, макросы действительно злы...

Ответ 1

Насколько я помню, вы не можете использовать другую директиву препроцессора в определении.

Ответ 2

Можно вставить хэш-токен в поток предварительно обработанной токены. Вы можете сделать это следующим образом:

#define MACRO(hash, name) hash include name
MACRO(#,"hello")

-expands:

# include "hello"

Однако стандарт явно исключает какой-либо дальнейший анализ такой строки для существования директив предварительной обработки [cpp.rescan]:

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

Ответ 3

Проблема заключается не в получении символа # на выходе вашего препроцессора.

По-видимому, вы хотите, чтобы препроцессор повторно просматривал ваш файл, чтобы иметь дело с недавно созданными директивами #include как часть расширения макросов. Это не работает. Если строка начинается С#, это инструкция для препроцессора и интерпретируется. Если строка не начинается С#, она подчиняется только препроцессорному преобразованию, включая макроподстановку. Это тест за один раз.

MACRO(Test)

не начинается С#. Поэтому он не интерпретируется как директива препроцессора; вместо этого он подчиняется правилам замены макросов.

Ответ 4

Это потому, что # имеет особое значение при использовании в макросе.

#  means quote the following token (which should be a macro parameter name)
## means concatenate the preceding and following tokens.

В вашей ситуации # не следует правильный токен. Поэтому в вашей ситуации нам нужно пройти уровень косвенности:

#define     QUOTE(name)     #name
#define     TEST(name)      QUOTE(name ## foo)

#include TEST(scot)

Ответ 5

Вы не можете этого сделать. Директивы препроцессора распознаются перед расширением макроса; если макрос расширяется во что-то, что выглядит как директива препроцессора, эта директива не будет распознана. Лучшее, что вы можете сделать, это создать макрос для имени файла:

#define MACRO(name) "name##foo"
...
#include MACRO(Test)

Ответ 6

Это может работать (оно работает для обычных макросов #define без параметров, но я не тестировал его с помощью макросов с параметрами).

#define MACRO(name) <name##foo>
#include MACRO(Test)

Ответ 7

#define HASH_SIGN #
BOOST_PP_CAT(HASH_SIGN, include)

Ответ 8

#define PARAM_NAME Param
#define GETNAME_(a) #a
#define GETNAME(a) GETNAME_(a)

int Param;
printf("%s = %i\n", GETNAME(PARAM_NAME), PARAM_NAME);