__builtin_round不是常量表达式

Amb*_*jak 8 c++ floating-point g++ built-in constexpr

在G ++中,在某些条件下,各种内置数学函数都是constexpr.例如,以下编译:

static constexpr double A = __builtin_sqrt(16.0);
static constexpr double B = __builtin_pow(A, 2.0);
Run Code Online (Sandbox Code Playgroud)

它们并不总是constexpr,它取决于论点.例如,__builtin_sqrt(NAN)当用作常量表达式时会导致编译错误.

但是我遇到了一个奇怪的案例,在我看来它应该是constexpr,但它不是:

static constexpr double value () { return 1.23; }
static constexpr double result = __builtin_round(__builtin_sqrt(value()));
Run Code Online (Sandbox Code Playgroud)

这会产生:

a.cpp:2:73: error: ‘__builtin_round(1.1090536506409416e+0)’ is not a constant expression
 static constexpr double result = __builtin_round(__builtin_sqrt(value()));
                                                                         ^
Run Code Online (Sandbox Code Playgroud)

我尝试过以上代码的变体,我发现:

  • 这个问题__builtin_round有一些特殊的作用.用其他内置数学函数替换它,例如sqrtpow解决错误.所以看起来__builtin_round只是缺乏constexpr支持.但...
  • 如果value()被文字替换1.23,那也会删除错误.
  • __builtin_sqrt仅删除,只__builtin_round(value())删除错误.

我想知道为什么round会以这种方式表现,如果有任何解决方法.

注意.我知道内置的数学函数及其constexpr-ness是非标准的编译器特有的功能.请不要告诉我如何不使用它,或者我不应该如何编写时间数学.在我的情况下,有constexpr数学是一个重要的功能,我很好依赖于G ++.

小智 4

我有另一个解决方法的想法。

有:使用辅助函数pass_through

template<typename T>
constexpr T&& pass_through (T&& t) { return static_cast<T&&>(t); }
Run Code Online (Sandbox Code Playgroud)

像这样使用它:

static constexpr double value () { return 1.23; }
static constexpr double result = __builtin_round(pass_through(__builtin_sqrt(value())));
Run Code Online (Sandbox Code Playgroud)

这段代码在G++中编译没有错误。

我也同意这个问题应该向GCC报告的观点。