In G++, various builtin math functions are constexpr under certain conditions. For example, the following compiles:
static constexpr double A = __builtin_sqrt(16.0);
static constexpr double B = __builtin_pow(A, 2.0);
They are not always constexpr though, it depends on the argument. For example, __builtin_sqrt(NAN)
results in a compile error when used as a constant expression.
But I'm hitting a strange case where it seems to me that it should be constexpr, but it is not:
static constexpr double value () { return 1.23; }
static constexpr double result = __builtin_round(__builtin_sqrt(value()));
This produces:
a.cpp:2:73: error: ‘__builtin_round(1.1090536506409416e+0)’ is not a constant expression
static constexpr double result = __builtin_round(__builtin_sqrt(value()));
^
I've tried variations of the above code, and I've found that:
- The
__builtin_round
has some special role in the problem. Replacing it with some other builtin math function, such assqrt
orpow
resolves the error. So would appear that__builtin_round
simply lacks constexpr support. But... - If
value()
is replaced by a literal1.23
, that too removes the error. - Removing
__builtin_sqrt
, leaving only__builtin_round(value())
, removes the error too.
I'd like to know why the round
is behaving in this way, and if there is any workaround.
NOTE. I am aware that the builtin math functions, with their constexpr-ness, are a non-standard compiler-specific feature. Please don't lecture me on how I should not be using this, or how I shouldn't be trying to do compile time math. In my case, having constexpr math is an important feature, and I'm fine with depending on G++.