Какая разница между макросами: #define STR (x) #x "и" #define STR (x) VAL (x) "с" #define VAL (x) #x "?
Когда я использую этот код:
#include <stdio.h>
#define STR(x) #x
int main(void)
{
printf(__FILE__ STR(__LINE__) "hello!\n");
return 0;
}
он печатает
hello.c__LINE__hello!
но когда я использую это:
#include <stdio.h>
#define STR(x) VAL(x)
#define VAL(x) #x
int main(void)
{
printf(__FILE__ STR(__LINE__) "hello!\n");
return 0;
}
он печатает
hello.c7hello!
какая разница между
#define STR(x) #x
и
#define STR(x) VAL(x)
#define VAL(x) #x
Ответы
Ответ 1
Аргументы макросов сами по себе являются макрорасширенными, за исключением тех случаев, когда имя макроса в макрообъекте отображается с помощью строкового элемента # или токена-пастера ##.
В первом случае аргумент STR не является макрорасширением, поэтому вы просто получаете имя макроса LINE.
Во втором случае аргумент STR макросвобождается, когда он подставляется в определение VAL, и поэтому он работает - вы получаете фактический номер строки, потому что макрос LINE расширяется.
Ответ 2
C99 N1256 стандартный проект 6.10.3.1/1 "Подстановка аргумента":
После того, как были определены аргументы для вызова функционально-подобного макроса, имеет место замена аргумента. Параметр в списке замещения, если не указано с помощью токена # или ## предварительной обработки или с помощью токена ## предварительной обработки (см. ниже), является заменяется соответствующим аргументом после того, как все макросы, содержащиеся в нем, были расширен. Перед заменой, каждый токен предварительной обработки аргументов полностью макрос заменили, как если бы они сформировали остальную часть файла предварительной обработки; нет другого доступны токеты предварительной обработки.
Итак, #
и ##
аргументы обрабатываются по-разному.