3.9 Директивы внутри аргументов макроса
Иногда удобно использовать директивы препроцессора внутри аргументов макроса. Стандарты C и C++ объявляют такое поведение неопределённым.
Версии CPP до 3.2 отклоняли такие конструкции с сообщением об ошибке. Это было единственное синтаксическое различие между обычными функциями и функциями-макросами, поэтому казалось привлекательным убрать это ограничение, и люди часто удивлялись, что они не могут использовать макросы таким образом. Кроме того, иногда люди использовали условную компиляцию в списке аргументов обычной библиотечной функции, такой как «printf», только для того, чтобы обнаружить, что после обновления библиотеки «printf» изменилась на функцию-макрос, и их код больше не компилировался. Поэтому с версии 3.2 мы изменили CPP так, чтобы он успешно обрабатывал произвольные директивы внутри аргументов макроса точно так же, как он бы обработало директиву, если бы вызов функции-макроса отсутствовал.
Если внутри вызова макроса этот макрос переопределяется, то новое определение вступает в силу ко времени предварительного расширения аргументов, но исходное определение всё ещё используется для замены аргументов. Вот патологический пример:
#define f(x) x x f (1 #undef f #define f 2 f)
который расширяется до
1 2 1 2
со смыслом, описанным выше.
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-5.5.0/cpp/Directives-Within-Macro-Arguments.html