我想测试在无穷大附近漂浮的行为。 为此,我天真地编写了以下代码:
#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 分配)。
据我所知,自 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;
最佳答案
我不是特别熟悉 float 规则,但我怀疑我们可能会与 [expr]/4 冲突:
If during the evaluation of an expression, the result is not mathematically defined or not in the range of representable values for its type, the behavior is undefined.
反过来,这意味着我们与 [expr.const]/2.6 发生冲突:
An expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine, would evaluate one of the following expressions: [...] an operation that would have undefined behavior as specified in [intro] through [cpp] of this document
这意味着 foo
的初始化器不是一个常量表达式,所以我们不能用它初始化一个 constexpr
对象。
如果 infinity() - epsilon()
为 float
定义良好,这是一个 clang 错误,代码格式正确。如果它没有为 float
明确定义,则这是一个 gcc 错误。
关于c++ - 无穷大不是 constexpr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46372614/