Замена родительских токенов в дочернем макросе - PullRequest
0 голосов
/ 29 марта 2019

Я пытаюсь заменить некоторые токены в вызываемом макросе, но не могу определить правильный порядок расширения и \ или отсрочки.Например:

#define EXPAND(...) __VA_ARGS__
#define REPLACE(hello,y) EXPAND(y)
REPLACE(goodbye, hello world)

На мой взгляд, макрос REPLACE будет вызывать макрос EXPAND, делая его функционально идентичным:

#define REPLACE(hello,y) hello world

Разрешение hello world бытьпреобразован в goodbye world.

Мой компилятор (MSVC 2017), похоже, этого не делает, поэтому я подозреваю, что я ошибаюсь.Я читал о расширении и отсрочке и перепробовал много разных комбинаций DEFER() и EXPAND(), но ни одна из них не дает результата, которого я добиваюсь.

Кто-нибудь знает, что яя делаю неправильно?

1 Ответ

0 голосов
/ 29 марта 2019

Это не то, как обрабатываются макропараметры, а не просто так. Если бы использование имени параметра макроса в аргументах макроса могло быть заменено, то было бы невозможно написать безопасные макросы: случайное использование имени параметра макроса привело бы к хаосу, и нет никаких причин, по которым необходимо, чтобы вызывающий макрос знать, как называются параметры. Параметры макроса являются локальными для расширения макроса, подобно тому, как параметры функции являются локальными для тела функции.

Вот фактический алгоритм подстановки из раздела 6.10.3.1/1 [Подстановка аргумента] стандарта C:

После того, как аргументы для вызова функционально-подобного макроса были идентифицированы, происходит подстановка аргументов. Параметр в списке замен & hellip; заменяется соответствующим аргументом после раскрытия всех содержащихся в нем макросов. Перед заменой токены предварительной обработки каждого аргумента полностью заменяются макросами, как если бы они образовывали остальную часть файла предварительной обработки; другие токены предварительной обработки недоступны.

Обратите внимание, что аргументы заменяются макросами до того, как будет помещено в расширение макроса. После этого имена параметров в списке замен перестают быть актуальными и не являются частью заменяемого текста.

Как только вызов макроса был заменен его расширением, полученные токены затем снова сканируются (& sect; 6.10.3.4: «Полученная последовательность токенов предварительной обработки затем сканируется вместе со всеми последующими токенами предварительной обработки исходного файла, для больше названий макросов для замены. "). Однако, поскольку вызов макроса был полностью заменен до этого повторного сканирования, маркеры параметров больше не отображаются.

Так что это конкретное решение вашей проблемы - тупик. Я рекомендую вам сделать шаг назад и сосредоточиться на проблеме, которую вы действительно хотите решить.

...