有没有办法要求编译器证明运行时表达式的属性,类似于
static_assert
,但不要求表达式为constexpr
?
一个简单的案例是这样的:
unsigned f(unsigned i) {
if (i == 0)
return 1;
static_assert(i != 0);
return i > 0 ? i + 20 : i + 30;
}
这无法编译,因为
i
不是常量表达式,这是有道理的。当在没有 static_assert 的情况下编译此函数时(https://godbolt.org/z/o3KjYGTGr),很明显编译器知道 i
在优化级别 -O2
不为 0。那么有没有办法要求编译器证明i
不为0,如果不能证明就中止编译呢?
使用此方法的一个实际情况是,在测试和最终使用该值之间存在大量代码,而无需运行时检查的开销:
if (i == 0)
return;
// many lines of code
// assert that i != 0 here
function_that_requires_a_nonzero_arg(i);
这是两部分,
使用 assert 用于测试运行时条件,在后来的 C++ 标准中我们应该得到契约,这是更 C++ 标准的方式,而断言是从 C 继承的,如果你想在发布模式下强制执行它那么你可以创建您自己的引发异常的断言。
您使用 假设属性 C++23,它告诉编译器针对始终为 true 的表达式进行优化。
编译器通常不会测试运行时条件是否为真,这只是一个优化机会,也许静态分析器可以证明这一点。