Come creare una stringa di caratteri dal valore di una macro C?

Ad esempio, come evitare di scrivere il “nome_completo” due volte?

#ifndef TEST_FUN # define TEST_FUN func_name # define TEST_FUN_NAME "func_name" #endif 

Mi piacerebbe seguire la regola Single Point of Truth .

Versione del preprocessore C:

 $ cpp --version cpp (GCC) 4.1.2 20070626 (Red Hat 4.1.2-14) 

Colui che è Timido * ti ha dato il germe di una risposta , ma solo il germe. La tecnica di base per convertire un valore in una stringa nel pre-processore C è infatti tramite l’operatore ‘#’, ma una semplice traslitterazione della soluzione proposta ottiene un errore di compilazione:

 #define TEST_FUNC test_func #define TEST_FUNC_NAME #TEST_FUNC #include  int main(void) { puts(TEST_FUNC_NAME); return(0); } 

L’errore di syntax è sulla riga ‘puts ()’ – il problema è un ‘# randagio’ nella fonte.

Nella sezione 6.10.3.2 dello standard C, “L’operatore #”, dice:

Ogni token di preelaborazione # nell’elenco di sostituzione per una macro simile alla funzione deve essere seguito da un parametro come successivo token di preelaborazione nell’elenco di sostituzione.

Il problema è che puoi convertire argomenti macro in stringhe, ma non puoi convertire elementi casuali che non siano macro argomenti.

Quindi, per ottenere l’effetto che cerchi, devi sicuramente fare del lavoro extra.

 #define FUNCTION_NAME(name) #name #define TEST_FUNC_NAME FUNCTION_NAME(test_func) #include  int main(void) { puts(TEST_FUNC_NAME); return(0); } 

Non sono completamente chiaro su come pensi di utilizzare i macro e su come prevedi di evitare del tutto la ripetizione. Questo esempio un po ‘più elaborato potrebbe essere più informativo. L’uso di una macro equivalente a STR_VALUE è un idioma necessario per ottenere il risultato desiderato.

 #define STR_VALUE(arg) #arg #define FUNCTION_NAME(name) STR_VALUE(name) #define TEST_FUNC test_func #define TEST_FUNC_NAME FUNCTION_NAME(TEST_FUNC) #include  static void TEST_FUNC(void) { printf("In function %s\n", TEST_FUNC_NAME); } int main(void) { puts(TEST_FUNC_NAME); TEST_FUNC(); return(0); } 

* Nel momento in cui questa risposta è stata scritta per la prima volta, il nome di shoosh è stato usato come “Shy” come parte del nome.

@ Jonathan Leffler: Grazie. La tua soluzione funziona.

Un esempio operativo completo:

 /** compile-time dispatch $ gcc -Wall -DTEST_FUN=another_func macro_sub.c -o macro_sub && ./macro_sub */ #include  #define QUOTE(name) #name #define STR(macro) QUOTE(macro) #ifndef TEST_FUN # define TEST_FUN some_func #endif #define TEST_FUN_NAME STR(TEST_FUN) void some_func(void) { printf("some_func() called\n"); } void another_func(void) { printf("do something else\n"); } int main(void) { TEST_FUN(); printf("TEST_FUN_NAME=%s\n", TEST_FUN_NAME); return 0; } 

Esempio:

 $ gcc -Wall -DTEST_FUN=another_func macro_sub.c -o macro_sub && ./macro_sub do something else TEST_FUN_NAME=another_func 
 #include  #define QUOTEME(x) #x #ifndef TEST_FUN # define TEST_FUN func_name # define TEST_FUN_NAME QUOTEME(TEST_FUN) #endif int main(void) { puts(TEST_FUN_NAME); return 0; } 

Riferimento: pagina del preprocessore C di Wikipedia

#define TEST_FUN_NAME #FUNC_NAME

guarda qui