为什么 std::nextafter 不是常量表达式?

问题描述 投票:0回答:1

为什么下面的代码对于 a2 没有问题,但对于 z1 却不能编译?

#include <cmath>    // std::nextafter
#include <limits>   // std::numeric_limits

int main ()
{
    constexpr float a1 {1.f};
    constexpr float a2 {std::nextafter(a1, std::numeric_limits<float>::max())};
    constexpr float z0 {0.f};
    constexpr float z1 {std::nextafter(z0, std::numeric_limits<float>::max())};
    
    return 0;
}

使用 GCC 13.2 编译

In file included from <source>:1:
/opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/cmath: In function 'int main()':
<source>:9:39:   in 'constexpr' expansion of 'std::nextafter(((float)z0), std::numeric_limits<float>::max())'
/opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/cmath:2417:32: error: '__builtin_nextafterf(0.0f, 3.40282347e+38f)' is not a constant expression
 2417 |   { return __builtin_nextafterf(__x, __y); }

因此GCC正确编译了a2,但无法编译z1。

注意: 即使使用 a2,Clang 14.0 和 MSVC 19.38 也有问题。

c++ constexpr c++23
1个回答
0
投票

回答您问题的标题:

为什么

std::nextafter
不是常量表达式?

在 C++ 中,常量表达式是可以在编译时求值的表达式。然而,

std::nextafter
不是常量表达式,因为它涉及无法在编译时确定的运行时计算

由于它的计算取决于输入值和底层系统的浮点表示,因此无法在编译时解析。

© www.soinside.com 2019 - 2024. All rights reserved.