По крайней мере, некоторые препроцессоры 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 это гарантирует?
Если нет, то в какой момент поведение переходит от C-определенного к GCC?
c
c-preprocessor
stringification
Питер Хози
источник
источник
Ответы:
Да, это гарантировано.
Это работает, потому что аргументы макроса сами раскрываются макросом, за исключением случаев, когда имя аргумента макроса появляется в теле макроса со строковым указателем # или лексем-вставкой ##.
6.10.3.1/1:
Итак, если вы это сделаете,
STR1(THE_ANSWER)
вы получите «THE_ANSWER», потому что аргумент STR1 не раскрывается макросом. Тем не менее, аргумент Str2 является макро-расширена , когда она замещена в определение Str2, который , следовательно , дает Str1 аргумент42
, с результатом «42».источник
Как отмечает Стив, это гарантировано, и это было гарантировано со времен стандарта C89 - это был стандарт, кодифицировавший операторы # и ## в макросах и предписывающий рекурсивно расширять макросы в args перед их заменой в тело, если и только если тело не применяет # или ## к аргументу. В этом отношении C99 не отличается от C89.
источник