static_assert 一个非 constexpr 表达式

问题描述 投票:0回答:1

有没有办法要求编译器证明运行时表达式的属性,类似于

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);
c++ assertion
1个回答
0
投票

这是两部分,

  1. 如何确保运行时变量始终满足条件。

使用 assert 用于测试运行时条件,在后来的 C++ 标准中我们应该得到契约,这是更 C++ 标准的方式,而断言是从 C 继承的,如果你想在发布模式下强制执行它那么你可以创建您自己的引发异常的断言。

  1. 如何告诉编译器根据始终为真的条件进行优化

您使用 假设属性 C++23,它告诉编译器针对始终为 true 的表达式进行优化。

编译器通常不会测试运行时条件是否为真,这只是一个优化机会,也许静态分析器可以证明这一点。

© www.soinside.com 2019 - 2024. All rights reserved.