Sto utilizzando alcune macro di registrazione, che dovrebbero stampare le informazioni fornite dalla macro __PRETTY_FUNCTION__
e, se necessario, nome e valore di un massimo di due argomenti. Una versione semplificata del mio codice è simileMacro variabile senza argomenti
template<typename Value1, typename Value2>
void Log(std::string const& function,
std::string const& variable_1 = "", Value1 value_1 = Value1(0),
std::string const& variable_2 = "", Value2 value_2 = Value2(0)) {
std::cout << function << " "
<< variable_1 << " " << value_1 << " "
<< variable_2 << " " << value_2 << std::endl;
}
#define LOG0() Log(__PRETTY_FUNCTION__)
#define VARIABLE(value) #value, value
#define LOG1(value) Log(__PRETTY_FUNCTION__, VARIABLE(value))
#define LOG2(value, value1) Log(__PRETTY_FUNCTION__, VARIABLE(value), VARIABLE(value1))
#define LOG(arg0, arg1, arg2, arg, ...) arg
#define CHOOSE(...) LOG(,##__VA_ARGS__, LOG2, LOG1, LOG0)
#define Debug(...) CHOOSE(__VA_ARGS__)(__VA_ARGS__)
posso usare queste macro come
Debug();
int x = 0;
Debug(x);
int y = 1;
Debug(x, y);
Quando compilo questo codice con clang ho un bel uscita contenente classe e informazioni funzione così come nome e valore delle variabili. Ma ricevo anche l'avviso che il codice conforme allo standard non può avere zero argomenti variadici.
warning: token pasting of ',' and __VA_ARGS__ is a GNU extension [-Wgnu-zero-variadic-macro-arguments]
#define CHOOSE(...) LOG(,##__VA_ARGS__, LOG2, LOG1, LOG0)
^
warning: must specify at least one argument for '...' parameter of variadic macro [-Wgnu-zero-variadic-macro-arguments]
Debug();
Gcc invece fallisce la compilazione con
error: expected primary-expression before ‘)’ token
#define LOG1(value) Log(__PRETTY_FUNCTION__, VARIABLE(value))
^
Debug();
Ovviamente è pericoloso lavorare con zero argomenti variadic.
- C'è un modo per trasformare questo codice in codice conforme standard senza rimuovere la comodità di avere una sola macro che richiede zero o due argomenti?
- Se questo non è possibile, c'è un modo per fare anche gcc compilare questo codice?
Il comportamento di ## __ VA_ARGS__ dipende dalla versione di CPP. Può essere semplice come aggiungere uno spazio bianco prima della virgola precedente ##: 'LOG (, ## __ VA_ARGS __, ...' – Pianosaurus
Inoltre, le tue macro funzionano come sono per me in g ++ 4.9.2, eccetto che g ++ non è in grado di dedurre il tipo di modello dei valori quando non vengono forniti. Hai pubblicato un esempio completo o manca qualcosa? – Pianosaurus