Almeno alcuni preprocessori C ti permettono di stringere il valore di una macro, piuttosto che il suo nome, facendolo passare attraverso una macro simile a una funzione ad un’altra che lo stringa:
#define STR1(x) #x #define STR2(x) STR1(x) #define THE_ANSWER 42 #define THE_ANSWER_STR STR2(THE_ANSWER) /* "42" */
Esempi di utilizzo qui .
Questo funziona, almeno in GCC e Clang (entrambi con -std=c99
), ma non sono sicuro di come funzioni in termini C-standard.
Questo comportamento è garantito da C99?
Se sì, come lo garantisce C99?
In caso negativo, a che punto il comportamento passa da C definito a GCC?
Sì, è garantito.
Funziona perché gli argomenti delle macro sono a loro volta macro espansi, tranne quando il nome dell’argomento macro viene visualizzato nel corpo della macro con l’identificatore # o il token-paster ##.
6.10.3.1/1:
… Dopo che gli argomenti per l’invocazione di una macro simile a una funzione sono stati identificati, si verifica la sostituzione dell’argomento. Un parametro nell’elenco di sostituzione, a meno che non sia preceduto da un token di preelaborazione # o ## o seguito da un token di preelaborazione ## (vedi sotto), viene sostituito dall’argomento corrispondente dopo che tutte le macro in esso contenute sono state espanse …
Quindi, se fai STR1(THE_ANSWER)
, ottieni “THE_ANSWER”, perché l’argomento di STR1 non è espanso in macro. Tuttavia, l’argomento di STR2 viene espanso in macro quando viene sostituito nella definizione di STR2, che pertanto fornisce a STR1 un argomento di 42
, con il risultato di “42”.
Come nota Steve, questo è garantito, ed è stato garantito dallo standard C89 – era lo standard che codificava gli operatori # e ## in macro e mandava ricorsivamente espandendo le macro in args prima di sostituirle nel corpo se e solo se il corpo non applica un # o ## all’argomento. C99 è invariato rispetto a C89 in questo senso.