无穷大不是constexpr

Infinity not constexpr

本文关键字:constexpr 无穷大      更新时间:2023-10-16

我想测试无穷大附近的浮子的行为。为此,我天真地写了以下代码:

#include <limits>
#include <iostream>
int main() {
    constexpr float foo = std::numeric_limits<float>::infinity() - std::numeric_limits<float>::epsilon();
    std::cout << foo << std::endl;
    return foo;
}

对我来说有趣的部分是,这在gcc 7.2中恢复了正常,但在clang 5上失败(抱怨 foo的非constexpr分配)。

afaik,因为C 11,std::numeric_limits<float>::infinity()infinity()constexpr,所以我想知道问题的问题在哪里。


编辑1:

删除了不必要的static_assert。感谢您指向分区。

和强制性Godbolt链接:https://godbolt.org/g/nd5yf9

编辑2:

请注意,相同的行为适用于:

constexpr float foo = std::numeric_limits<float>::infinity() - 100.0f;

我对浮点规则并不特别熟悉,但我怀疑我们可能会在[expr]/4:

的情况下运行

如果在评估表达式期间,该结果在数学上没有定义或不在其类型的代表值范围内,则行为是未定义的。

这又意味着我们在[expr.const]/2.6:

的情况下运行

表达式E是核心常数表达式]通过此文档的[CPP]

这意味着foo的初始化器不是恒定的表达式,因此我们不能用它初始化constexpr对象。


如果infinity() - epsilon()针对float定义明确,则这是一个clang虫,代码已良好。如果float的定义不明确,则是GCC错误。