I am trying to write a macro dbgassert
similar to the standard assert
. In addition to what assert
does, I want to dbgassert
Just as a note, I was able to figure out another means to solve the trailing comma issue, in addition to @cmaster and @ds27680's solution. Since having __VA_ARGS__
leads to an extra comma, I can pack __VA_ARGS__
into a std::tuple
or a function call, and use the tuple/result as a parameter of the real function. Now empty __VA_ARGS__
's won't be a problem because its packed into one valid value (i.e. either an empty tuple or the return value of a nullary function). I guess this is longer in code, but a bit more portable without involving ##
.
The above two cases are shown in the dbgassert
and dbgassert1
macros in the code below, respectively.
#include
#include
#include
using namespace std;
template
string print_tuple(tuple tp) {
return ""; //print the tuple...
}
template
void realdbgassert(tuple info,const char *msg, const char *file, int line) {
cout << "Assertion failed! \nFile " << file << ", Line " << line << endl
<< " Expression: " << msg << endl
<< " Info: " << print_tuple(info) << endl;
std::abort();
}
#define dbgassert(EX,...) \
(void)((EX) || (realdbgassert (std::tie(__VA_ARGS__),#EX,__FILE__, __LINE__),0))
void realdbgassert1(string info,const char *msg, const char *file, int line) {
cout << "Assertion failed! \nFile " << file << ", Line " << line << endl
<< " Expression: " << msg << endl
<< " Info: " << info << endl;
std::abort();
}
template
string print_info(Args ... args) {
return ""; //print stuff
}
#define dbgassert1(EX,...) \
(void)((EX) || (realdbgassert1 (print_info(__VA_ARGS__),#EX,__FILE__, __LINE__),0))
int main() {
dbgassert(1>2,"right","yes"); //OK
dbgassert(1>2,"right"); //OK
dbgassert(1>2); //OK now
dbgassert1(1>2); //OK too
}