2015-09-11 9 views
5

dire che ho un versione del prodotto macro-definito C come questo:Convertire un argomento di macro in una stringa costante e tenere conto delle virgole

#define FOO_VERSION 1,0,0,1 

E voglio stamparlo in fase di esecuzione:

#define STRING_VALUE(x) #x 

int main() 
{ 
    std::cout << STRING_VALUE(FOO_VERSION) << std::endl; 
} 

Questo emetterà una stringa "FOO_VERSION", non "1,0,0,1". L'argomento macro "FOO_VERSION" non viene sostituito. Così ho provato ancora una volta come questo :

#define STRING_VALUE(x) STRING_VALUE__(x) 
#define STRING_VALUE__(x) #x 

int main() 
{ 
    std::cout << STRING_VALUE(FOO_VERSION) << std::endl; 
} 

Funziona, in Visual C++ 2013.

Questa è un'applicazione multipiattaforma, anche se ci sono solo cinque righe di codice. Quando uso clang per compilare il codice, viene visualizzato un errore di compilazione - : "troppi argomenti forniti per la funzione macro" invocazione ". Immagino che il motivo sia la virgola definita in "FOO_VERSION". Così la terza versione:

#define STRING_VALUE(x) STRING_VALUE__(x) 
#define STRING_VALUE__(a, b, c, d) #a "," #b "," #c "," #d 

int main() 
{ 
    std::cout << STRING_VALUE(FOO_VERSION) << std::endl; 
} 

Questo codice funziona in clang, ma Visual C++ emette un avvertimento: "non abbastanza parametri effettivi per la macro 'STRING_VALUE__'" a tempo di compilazione, naturalmente, il run-time l'output non è giusto.

La mia domanda: è definito questo comportamento del pre-processore? Posso avere una versione universale della macro STRING_VALUE?

risposta

10

Si può trattare l'argomento come un unico macro variadic:

#define FOO_VERSION 1,0,0,1 

#define STRING_VALUE(...) STRING_VALUE__(__VA_ARGS__) 
#define STRING_VALUE__(...) #__VA_ARGS__ 

Questo sembra funzionare con gcc e Visual C++.

+0

Perché non ci ho pensato? – amanjiang