本文介绍了无限不是constexpr的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-22 13:51