Przynajmniej niektóre preprocesory języka C pozwalają na zdefiniowanie wartości makra, a nie jego nazwy, poprzez przekazanie go przez jedno makro podobne do funkcji do drugiego, które je określa:
#define STR1(x) #x
#define STR2(x) STR1(x)
#define THE_ANSWER 42
#define THE_ANSWER_STR STR2(THE_ANSWER) /* "42" */
Przykładowe przypadki użycia tutaj .
To działa, przynajmniej w GCC i Clang (oba z -std=c99
), ale nie jestem pewien, jak to działa w warunkach standardu C.
Czy takie zachowanie gwarantuje C99?
Jeśli tak, w jaki sposób C99 to gwarantuje?
Jeśli nie, w którym momencie zachowanie zmienia się ze zdefiniowanego w C na zdefiniowane w GCC?
c
c-preprocessor
stringification
Peter Hosey
źródło
źródło
Odpowiedzi:
Tak, to gwarantowane.
Działa, ponieważ argumenty makr są same w sobie rozwijane w makra, z wyjątkiem sytuacji , gdy nazwa argumentu makra pojawia się w treści makra z ciągiem znaków # lub paster-tokenem ##.
6.10.3.1/1:
Tak więc, jeśli to zrobisz
STR1(THE_ANSWER)
, otrzymasz „THE_ANSWER”, ponieważ argument STR1 nie jest rozszerzany w makra. Jednak argument STR2 jest rozszerzany w makro, gdy jest podstawiany do definicji STR2, co w związku z tym daje STR1 argument o42
wartości „42”.źródło
Jak zauważa Steve, jest to gwarantowane i jest gwarantowane od czasu standardu C89 - był to standard, w którym skodyfikowano operatory # i ## w makrach i nakazuje rekurencyjne rozszerzanie makr w argumentach przed zastąpieniem ich w treści wtedy i tylko wtedy, gdy treść nie stosuje znaku # ani ## do argumentu. Pod tym względem C99 pozostaje niezmienione od C89.
źródło