Reputation: 85975
Today I discovered some of my assertion functions are still exist and being called in release build. Here's an example of my assertion function.
bool const isDebugMode()
{
return false; // Will be controlled by preprocessor flag.
}
void assertWithReason(bool const condition, std::string const reason = "")
{
if (isDebugMode() and not condition)
{
abort();
}
}
I think some side-effect in condition expression is preventing eliminating the assertion call.
For example,
assertWithReason(glGetError() == GL_NO_ERROR);
I expected this assertion call to be eliminated, but it is not. Because it is being executed before checking debug-build.
I am not sure how C++ handles this case, but as C++ is very strict language, it doesn't seem to be eliminated unless I put some special flag. Anyway, I intentionally wrote the assertions to be removed in release build.
Is it possible to write a function which is surely removed in release build in C++? Of course I can use preprocessor macro, but I want to avoid using preprocessor macro as much as possible.
I am using Clang, and compiler specific extension (such as GCC attribute) is also fine.
Upvotes: 0
Views: 181
Reputation: 129364
I quite like using macros for this purpose. Yes, I know, Macros are evil, but just like knives (used wrong) are evil, they come in handy if you use them right.
#define MY_ASSERT(x) do {\
if (is_debug() && !x) assertFailed(__FILE__, __LINE__, __FUNCTION__, #x);\
} while(0);
Now you can also show where it failed (my_drawfunc.cpp: 34 : my_do_draw(): assertion failed: glGetError == GL_NO_ERROR
or something like that.
Upvotes: 2
Reputation: 5412
In C++11 you can use lambda expressions. It is likely that constant propogation will make it so that is_debug is never evaulated, and even if it is, the lambda is not called.
class Debug { enum { is_debug = 1; } };
template <class F>
void assert(F f) {
if (is_debug && !f()) abort();
}
{
int x = 6;
assert([&]() { return x == 6; });
}
Upvotes: 1