使用assert帮助编译器更好地进行优化

gez*_*eza 16 c++

考虑以下代码:

void foo(int n) {
    assert(n>=0&&n<=3);

    for (int i=0; i<n; i++) {
        doSomething();
    }
}
Run Code Online (Sandbox Code Playgroud)

这里有一个断言:n介于[0; 3]之间.断言通常用于检查程序员的错误.但是在这里,它可以用作n[0; 3]之间的编译器的提示,因此它可以更好地进行优化.也许它可以展开循环,并使用跳转.

对于GCC,我们可以手动帮助编译器:

if (!(n>=0&&n<=3)) __builtin_unreachable();
Run Code Online (Sandbox Code Playgroud)

在这里,GCC实际上被告知n在[0; 3]之间,因此它可以生成更好的代码.

我的问题是:是否可以创建一个(可能是编译器相关的)new_assert宏,它可以在发布版本中告诉编译器的提示?此解决方案必须是透明的,因此它可以完全替代assert宏.例如,如果它具有副作用,则不能在发布版本中调用" new_assert(func());" func().

或者,如果不可能,另一个有用的new_assert可能是,如果条件不允许有副作用(这会导致编译时错误),所以我们可以if (!(cond)) __builtin_unreachable();在发布版本中使用而不用担心会cond产生副作用.即是否有可能创建一个new_assert检查其条件是否有副作用?

是一个相关的问题.

是一个非常相似的问题,但这次我问是否有可能为assert宏创建一个完整的替换(所以我们可以避免手动注释代码)

rep*_*vsd 1

我认为,如果您只是在 new_assert() 宏中添加未定义的行为,编译器将决定这些前提条件是不可协商的。并生成更快的代码。

但是,如果您的代码有错误,并且断言失败,则任何事情都可能发生。