我想测试无穷远处浮子的行为。 为此我天真地写了下面的代码:
#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;
答案 0 :(得分:8)
我对浮点规则并不是特别熟悉,但我怀疑我们可能与[expr]/4发生冲突:
如果在评估表达式期间,结果未在数学上定义或未在其类型的可表示值范围内,则行为未定义。
反过来,这意味着我们与[expr.const]/2.6:
发生冲突表达式e是核心常量表达式,除非根据抽象机器的规则评估e将评估以下表达式之一:[...]具有[intro]中指定的未定义行为的操作]通过本文件的[cpp]
这意味着foo
的初始值设定项不是常量表达式,因此我们无法用它初始化constexpr
对象。
如果infinity() - epsilon()
的{{1}}定义明确,则这是一个铿锵的错误,代码格式正确。如果float
没有明确定义,这是一个gcc错误。