Tue
11
Sep 2018
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 :)