今天我发现我的一些断言函数仍然存在并在发布版本中被调用。这是我的断言函数的一个例子。
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();
}
}
我认为条件表达式中的一些副作用是阻止消除断言调用。
例如,
assertWithReason(glGetError() == GL_NO_ERROR);
我预计这个断言呼叫会被淘汰,但事实并非如此。因为它在检查debug-build之前正在执行。
我不确定C ++如何处理这种情况,但由于C ++是非常严格的语言,除非我放置一些特殊的标志,否则它似乎不会被删除。无论如何,我故意写了要在发布版本中删除的断言。
是否有可能在C ++的发布版本中编写一个肯定删除的函数? 当然我可以使用预处理器宏,但我想尽可能避免使用预处理器宏。
我正在使用Clang,编译器特定的扩展名(例如GCC属性)也没问题。
答案 0 :(得分:2)
我非常喜欢将宏用于此目的。是的,我知道,Macros 邪恶,但就像刀(使用错误)是邪恶的,如果你正确使用它们就会派上用场。
#define MY_ASSERT(x) do {\
if (is_debug() && !x) assertFailed(__FILE__, __LINE__, __FUNCTION__, #x);\
} while(0);
现在您还可以显示失败的位置(my_drawfunc.cpp: 34 : my_do_draw(): assertion failed: glGetError == GL_NO_ERROR
或类似的内容。
答案 1 :(得分:1)
在C ++ 11中,您可以使用lambda表达式。持续传播可能会使得is_debug永远不会被评估,即使它是,也不会调用lambda。
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; });
}