/ / Втілення символу # у макросі #define? - c ++, c, макроси, c-препроцесор, препроцесор-директива

Вихід із символу # у #define макросі? - c + +, c, макроси, c-препроцесор, директива передпроцесора

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

Наприклад, я хочу зробити щось подібне:

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

І використовуйте його таким чином:

MACRO(Test)

Що розшириться до:

#include "Testfoo"

Покірний знак # викликає препроцесора до барфу. MinGW дає мені таку помилку:

"#" is not followed by a macro parameter

Я думаю, мені потрібно уникнути знака #, але я не знаю, якщо це навіть можливо.

Так, макроси дійсно злі ...

Відповіді:

28 для відповіді № 1

Наскільки я пам'ятаю, ви не можете використовувати іншу директиву препроцесора в define.


30 за відповідь № 2

Це є можна вставити хеш-маркер у попередньо оброблений потік маркера. Ви можете це зробити так:

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

—Розширюється на:

# include "hello"

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

Послідовність маркера попередньої обробки, що повністю замінена, не обробляється як директива попередньої обробки, навіть якщо вона нагадує одну.


27 за відповідь № 3

Проблема насправді не є символом # у виході вашого препроцесора.

Мабуть, ви хочете, щоб препроцесор повторно проаналізувавфайл, щоб мати справу з новоствореними директивами #include як частину розширення макросу. Якщо лінія починається з #, вона є інструкцією для препроцесора і інтерпретується. Якщо рядок не починається з #, він підлягає лише перетворенням препроцесора, включаючи заміну макросу. Це тест один раз за лінію.

MACRO(Test)

не починається з #. Тому він не інтерпретується як директива препроцесора; замість цього застосовуються правила заміни макросів.


10 за відповідь № 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)

6 за відповідь № 5

Ви не можете це зробити. Передпроцесорні директиви розпізнаються перед розширенням макросу; якщо макрос розгортається у те, що виглядає як директива препроцесора, ця директива не розпізнається. Найкраще ви можете створити макрос для імені файлу:

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

2 для відповіді № 6

Це може робота (вона працює для регулярних #define макроси без параметрів, але я не перевірив його макросами з параметрами).

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

0 для відповіді № 7
#define HASH_SIGN #
BOOST_PP_CAT(HASH_SIGN, include)

0 для відповіді № 8
#define PARAM_NAME Param
#define GETNAME_(a) #a
#define GETNAME(a) GETNAME_(a)

int Param;
printf("%s = %in", GETNAME(PARAM_NAME), PARAM_NAME);