问题描述
我想测试无限附近的浮点数的行为。为此,我天真地写了以下代码:
I wanted to test the behavior of floats near infinity.For that I naively wrote the following code:
#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赋值)。
The interesting part to me was that this compiles fine in GCC 7.2 but fails on Clang 5 (complaining about non-constexpr assign of foo
).
AFAIK,因为C ++ 11, std :: numeric_limits< float> :: infinity()
和 infinity()
是 constexpr
,所以我想知道Clang的问题在哪里。
AFAIK, since C++11, std::numeric_limits<float>::infinity()
and infinity()
are constexpr
, so I am wondering where the problem lies for Clang.
编辑1:
删除了不必要的 static_assert
。
感谢您指向被0除。IMO引用的标准文本在此处不适用!?
Removed unnecessary static_assert
.Thanks for pointing to division by 0. IMO the quoted standards text there does not apply here!?
还有强制性的godbolt链接:
And the obligatory godbolt link: https://godbolt.org/g/Nd5yF9
编辑2:
请注意,相同的行为适用于:
Note that the same behavior applies to:
constexpr float foo = std::numeric_limits<float>::infinity() - 100.0f;
推荐答案
我对浮点规则不是特别熟悉,但我怀疑我们可能与:
I'm not particularly familiar with floating point rules, but I'd suspect that we might be running afoul of [expr]/4:
反过来,这意味着我们违反了:
Which, in turn, means we run afoul of [expr.const]/2.6:
foo
不是常量表达式,因此我们无法使用它初始化 constexpr
对象。
That means the initializer for foo
isn't a constant expression, so we can't initialize a constexpr
object with it.
如果 infinity()-epsilon()
很好-为 float
定义的,这是一个clang错误,代码格式正确。如果对 float
的定义不明确,则说明这是gcc错误。
If infinity() - epsilon()
is well-defined for float
, this is a clang bug, the code is well-formed. If it's not well-defined for float
, this is a gcc bug.
这篇关于无限不是constexpr的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!