Расширение токена препроцессора
Моя ментальная модель работы препроцессора, по-видимому, неполна, и это сводит меня с ума.
Я хочу объединить два токена, но сначала нужно развернуть второй токен.
#define ANSWER 42
#define FOO foo_ ## ANSWER
Здесь FOO
расширяется до foo_ANSWER
, но я хочу, чтобы он был foo_42
. Поэтому я определяю макрос MERGE
в надежде, что это каким-то образом расширит аргументы перед конкатенацией:
#define MERGE(x, y) x ## y
#define BAR MERGE(bar_, ANSWER)
Но BAR
по-прежнему расширяется до bar_ANSWER
вместо bar_42
. Поэтому я определяю еще один макрос HELPER
:
#define HELPER(x, y) MERGE(x, y)
#define BAZ HELPER(baz_, ANSWER)
И теперь BAZ
успешно расширен до baz_42
. На данный момент это кажется мне волшебным.
Может ли кто-нибудь объяснить это поведение мне? Как правила расширения работают точно?
Ответы
Ответ 1
Прочитайте ответ на свой вопрос здесь:
Проблема в том, что когда у вас есть макрозамена, препроцессор будет только расширять макросы рекурсивно, если ни шнуровка оператор # или приклеивание маркеров к нему применяется оператор ##. Так что вы должны использовать некоторые дополнительные слои косвенности, вы можете использовать оператор маркировки с помощью рекурсивно расширенный аргумент
Ответ 2
Конкатенация токена не расширяет макросы при выполнении конкатенации [ref].
Чтобы пройти мимо этого, вы используете уровень косвенности и получаете препроцессор для расширения макросов перед конкатенацией.
#define STEP1(x, y) STEP2(x, y) // x and y will be expanded before the call to STEP2
#define STEP2(x, y) x ## y // x and y will not be expanded, just pasted