Today, while programming in C++, I wanted to write an assert-like macro that would throw an exception when given condition is not satisfied. I wanted to include as much information as possible in the message string. I know that condition expression, which is argument of my macro, can be turned into a string by using #
preprocessor operator.
Next, I searched for a way to also obtain name of current function. At first, I found __func__
, as described here (C++11) and here (C99). Unfortunately, following code fails to compile:
#define CHECK(cond) if(!(cond)) { \
throw std::runtime_error("ERROR: Condition " #cond " in function " __func__);
void ProcessData()
{
CHECK(itemCount > 0); // Compilation error!
// (...)
}
This is because this identifier is actually an implicit local variable static const char __func__ [] = "..."
.
Then I recalled that Visual Studio defines __FUNCTION__
macro, as custom Microsoft extension. See documentation here. This one works as I expected - it can be concatenated with other strings, because it's a string literal. Following macro definition fixes the problem:
#define CHECK(cond) if(!(cond)) \
{ throw std::runtime_error("ERROR: Condition " #cond " in function " __FUNCTION__); }
When itemCount
is 0, exception is thrown and ex.what()
returns following string:
ERROR: Condition itemCount > 0 in function ProcessData
Well... For any experienced C++ developer, it should be no surprise that C++ standard committee comes up with solutions that are far from being useful in practice :)
Top comments (1)
You would appreciate D similar feature. If you run this example you can see that the macros (they are called special tokens actually in D) expand to the caller (__LINE__ gives 7).
That's very useful for logging or custom assertion functions.