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

Using assert to help the compiler to optimize better

本文关键字:优化 更好 编译器 assert 帮助 使用      更新时间:2023-10-16

请考虑以下代码:

void foo(int n) {
assert(n>=0&&n<=3);
for (int i=0; i<n; i++) {
doSomething();
}
}

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

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

if (!(n>=0&&n<=3)) __builtin_unreachable();

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

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

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

这是一个相关的问题。

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

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

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

你可以使用来自GNU的Gnulib的跨平台宏assure' from'。