Infinity not constexpr

时间:2017-09-22 20:17:45

标签: c++ c++17

我想测试无穷远处浮子的行为。 为此我天真地写了下面的代码:

#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,所以我想知道Clang的问题在哪里。

编辑1:

删除了不必要的static_assert。 感谢您指出除以0. IMO引用的标准文本在这里不适用!?

强制性的神盾链接:https://godbolt.org/g/Nd5yF9

编辑2:

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

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

1 个答案:

答案 0 :(得分:8)

我对浮点规则并不是特别熟悉,但我怀疑我们可能与[expr]/4发生冲突:

  

如果在评估表达式期间,结果未在数学上定义或未在其类型的可表示值范围内,则行为未定义。

反过来,这意味着我们与[expr.const]/2.6

发生冲突
  

表达式e是核心常量表达式,除非根据抽象机器的规则评估e将评估以下表达式之一:[...]具有[intro]中指定的未定义行为的操作]通过本文件的[cpp]

这意味着foo的初始值设定项不是常量表达式,因此我们无法用它初始化constexpr对象。

如果infinity() - epsilon()的{​​{1}}定义明确,则这是一个铿锵的错误,代码格式正确。如果float没有明确定义,这是一个gcc错误。