Ответ 1
Насколько я помню, вы не можете использовать другую директиву препроцессора в определении.
Не вдаваясь в детали gory, я хочу использовать макрос #define
, который будет расширяться до #include
, но знак '#' путает препроцессор (поскольку он считает, что я хочу привести аргумент.)
Например, я хочу сделать что-то вроде этого:
#define MACRO(name) #include "name##foo"
И используйте его таким образом:
MACRO(Test)
который будет расширяться до:
#include "Testfoo"
Смиренный знак # вызывает препроцессор barf. MinGW дает мне следующую ошибку:
'#' is not followed by a macro parameter
Думаю, мне нужно сбегать от знака #, но я этого не сделаю, если это возможно.
Да, макросы действительно злы...
Насколько я помню, вы не можете использовать другую директиву препроцессора в определении.
Можно вставить хэш-токен в поток предварительно обработанной токены. Вы можете сделать это следующим образом:
#define MACRO(hash, name) hash include name
MACRO(#,"hello")
-expands:
# include "hello"
Однако стандарт явно исключает какой-либо дальнейший анализ такой строки для существования директив предварительной обработки [cpp.rescan]:
Полученная полностью макрозаменяемая последовательность токенов предварительной обработки не обрабатывается как директива предварительной обработки, даже если она напоминает ее.
Проблема заключается не в получении символа # на выходе вашего препроцессора.
По-видимому, вы хотите, чтобы препроцессор повторно просматривал ваш файл, чтобы иметь дело с недавно созданными директивами #include как часть расширения макросов. Это не работает. Если строка начинается С#, это инструкция для препроцессора и интерпретируется. Если строка не начинается С#, она подчиняется только препроцессорному преобразованию, включая макроподстановку. Это тест за один раз.
MACRO(Test)
не начинается С#. Поэтому он не интерпретируется как директива препроцессора; вместо этого он подчиняется правилам замены макросов.
Это потому, что # имеет особое значение при использовании в макросе.
# 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)
Вы не можете этого сделать. Директивы препроцессора распознаются перед расширением макроса; если макрос расширяется во что-то, что выглядит как директива препроцессора, эта директива не будет распознана. Лучшее, что вы можете сделать, это создать макрос для имени файла:
#define MACRO(name) "name##foo"
...
#include MACRO(Test)
Это может работать (оно работает для обычных макросов #define
без параметров, но я не тестировал его с помощью макросов с параметрами).
#define MACRO(name) <name##foo>
#include MACRO(Test)
#define HASH_SIGN #
BOOST_PP_CAT(HASH_SIGN, include)
#define PARAM_NAME Param
#define GETNAME_(a) #a
#define GETNAME(a) GETNAME_(a)
int Param;
printf("%s = %i\n", GETNAME(PARAM_NAME), PARAM_NAME);