0

今天我发现我的一些断言函数仍然存在并且在发布版本中被调用。这是我的断言函数的一个例子。

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);

我预计这个断言调用会被消除,但事实并非如此。因为它是在检查调试构建之前执行的。

我不确定 C++ 如何处理这种情况,但由于 C++ 是非常严格的语言,除非我放置一些特殊标志,否则它似乎不会被淘汰。无论如何,我故意写了要在发布版本中删除的断言。

是否可以编写一个在 C++ 的发布版本中肯定被删除的函数?我当然可以使用预处理器宏,但我想尽可能避免使用预处理器宏。

我正在使用 Clang,编译器特定的扩展(例如 GCC 属性)也可以。

4

2 回答 2

2

我非常喜欢为此目的使用宏。是的,我知道,宏是邪恶的,但就像刀(使用错误)是邪恶的一样,如果你正确使用它们,它们会派上用场。

 #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或类似的东西。

于 2013-07-25T11:49:13.620 回答
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; });
}
于 2013-07-25T11:32:55.660 回答