Подтвердить что ты не робот

Расширение токена препроцессора

Моя ментальная модель работы препроцессора, по-видимому, неполна, и это сводит меня с ума.

Я хочу объединить два токена, но сначала нужно развернуть второй токен.

#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. На данный момент это кажется мне волшебным.

Может ли кто-нибудь объяснить это поведение мне? Как правила расширения работают точно?

4b9b3361

Ответ 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