Вопрос

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

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

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

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

MACRO(Test)

Который расширится до:

#include "Testfoo"

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

'#' is not followed by a macro parameter

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

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

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

Решение

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

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

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

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

— расширяется до:

# 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);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top