优化,断言和释放模式

时间:2014-05-17 08:33:53

标签: c++ c optimization assert static-assert

考虑一个函数

void f() {
   assert(condition);

   ...
}

在启用断言的调试模式下,编译器可以自由地假定condition成立,因为如果没有,则不会执行剩余的代码。

但是,在发布模式下,我相信编译器只会看到

void f() {
   ...
}

并且不能再假设condition

是否有任何编译器指令或静态断言技巧让编译器了解某些不变量?

2 个答案:

答案 0 :(得分:5)

这在便携式C或C ++中无法完成。

某些编译器提供内部函数,例如__assume(对于MSVC)和__builtin_unreachable(对于GCC,ICC和Clang),可用于此目的

例如:

void f() {
    __assume(condition); //For MSVC
    /*...*/
}

void f() {
    if (!condition) __builtin_unreachable(); //for GCC and Clang
    /*...*/
}

答案 1 :(得分:1)

动词的一部分"假设",这使得这个问题有点模糊,(让我担心你对编译器真正的作用有了真正的理解)assert是一个定义NDEBUG时(通常在发布版本中)替换为空的宏,并且 - 当在调试版本中使用时 - 如果 condition 不为真,则会引发错误。

关键在于,程序是"正确的"仅当条件始终为真时。在你证明它之后(在测试版本中),即使在发布代码中也没有必要继续证明它。

如果"条件"更微妙的问题可能是本身有一个副作用,你不想在发布版本中删除。

在这种情况下,只需输入" condition"从断言中输出,将结果存储在bool中并在bool上断言,如

bool condition_fine = (condition);
assert(condition_fine);

这允许在任何情况下评估条件,但从发布版本中删除错误检查。