Как именно работает трюк с двойной строкой?


по крайней мере, некоторых C препроцессоры позволяют вам строчить значение макроса, а не его имя, передавая его через один функциональный макрос другому, который его строчит:

#define STR1(x) #x
#define STR2(x) STR1(x)
#define THE_ANSWER 42
#define THE_ANSWER_STR STR2(THE_ANSWER) /* "42" */

пример использования здесь.

Это действительно работает, по крайней мере, в GCC и Clang (оба с -std=c99), но я не уверена как он работает в C-стандартных условиях.

это поведение гарантируется C99?
Если да, то как работает C99 гарантировать это?
Если нет, то в какой момент поведения с определенными Оук-определенными?

2 78

2 ответа:

Да, это гарантировано.

это работает, потому что аргументы макросов сами макро-расширены,кроме где имя аргумента макроса отображается в теле макроса со строковым символом # или маркером-Пастером ##.

6.10.3.1/1:

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

Так что, если вы делаете STR1(THE_ANSWER) тогда вы получаете "THE_ANSWER", потому что аргумент STR1 не является макрорасширенным. Однако аргумент STR2 и макрос расширяется, когда он подставляется в определение STR2, что, следовательно, дает STR1 аргумент 42, в результате из "42".

Как отмечает Стив, это гарантировано, и это было гарантировано с тех пор, как стандарт C89 - это был стандарт, кодифицированный # и ## операторы в макросах и мандаты рекурсивно расширяют макросы в args перед их заменой в теле тогда и только тогда, когда тело не применяет # или ## аргумент. C99 в этом отношении не отличается от C89.