I am using some logging macros, which are supposed to print out the information provided by the __PRETTY_FUNCTION__
macro and if needed name and value of up to two arguments.
A simplified version of my code looks like
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__)
I can use these macros like
Debug();
int x = 0;
Debug(x);
int y = 1;
Debug(x, y);
When I compile this code with clang I get a nice output containing class and function information as well as name and value of the variables. But I also get the warning that standard compliant code is not allowed to have zero variadic arguments.
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 on the other hand fails to compile with
error: expected primary-expression before ‘)’ token
#define LOG1(value) Log(__PRETTY_FUNCTION__, VARIABLE(value))
^
Debug();
Obviously it is dangerous to work with zero variadic arguments.
- Is there any way that I can turn this code into standard compliant code without removing the convenience of having just one macro that takes zero to two arguments?
- If this is not possible, is there a way to make also gcc compile this code?