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