По крайней мере некоторые препроцессоры C позволяют Вам stringize значение макроса, а не его имя, путем передачи его посредством одного подобного функции макроса другому что stringizes он:
#define STR1(x) #x
#define STR2(x) STR1(x)
#define THE_ANSWER 42
#define THE_ANSWER_STR STR2(THE_ANSWER) /* "42" */
Варианты использования в качестве примера здесь.
Это действительно работает, по крайней мере, в GCC и Лязге (оба с -std=c99
), но я не уверен, как это работает в условиях C-стандарта.
Это поведение гарантируется C99?
Если так, как C99 гарантирует это?
В противном случае в том, какая точка поведение идет от C-defined до GCC-определенного?
Да, это гарантировано.
Это работает, потому что аргументы макросов сами по себе макро-развернуты, за исключением , когда имя аргумента макроса появляется в теле макроса со строкоификатором # или маркером##.
6.10.3.1/1:
... После аргументов за вызов функционального макроса были идентифицированы, аргумент происходит подмена. Параметр в списке замены, если перед предварительной обработкой # или ## токен или за которым следует ## токен препроцессирования (см. ниже), заменен соответствующим аргументом после всех содержащихся в нем макросов были расширены...
Таким образом, если вы сделаете STR1(THE_ANSWER)
, то вы получите «THE_ANSWER», потому что аргумент STR1 не является макрорассыпным. Однако аргумент STR2 макрорасширяется при его замене в определение STR2, что, следовательно, дает STR1 аргумент 42
с результатом «42».
Как отмечает Стив, это гарантировано, и это гарантируется со времени выхода стандарта C89 - этого стандарта кодифицировал операторы # и ## в макросах и мандатах. рекурсивно расширять макросы в args перед их заменой в тело тогда и только тогда, когда тело не применяет # или ## к аргументу. В этом отношении C99 не отличается от C89.