The following code doesn't compile with clang and libc++: https://godbolt.org/z/rDL-_K
#include <array>
int main() {
static constexpr std::array<int, 0> xs{};
constexpr auto i = xs.begin(); // non-constexpr function 'begin' cannot be used in a constant expression
return 0;
}
But if you change the 0
to a 1
, it compiles.
Is this a bug in libc++ or is there a good reason for it? How could I work around this if I have generic constexpr code that uses begin
/end
?
(I've seen this question, but my example intentionally uses static
to avoid this problem.)
A reference may be declared as constexpr when both these conditions are met: The referenced object is initialized by a constant expression, and any implicit conversions invoked during initialization are also constant expressions. All declarations of a constexpr variable or function must have the constexpr specifier.
constexpr stands for constant expression and is used to specify that a variable or function can be used in a constant expression, an expression that can be evaluated at compile time. The key point of constexpr is that it can be executed at compile time.
Static specifies the lifetime of the variable. A static constexpr variable has to be set at compilation, because its lifetime is the the whole program. Without the static keyword, the compiler isn't bound to set the value at compilation, and could decide to set it later.
The constexpr keyword implies inline. Performing computations at compiletime can have many advantages over doing them at runtime. Firstly it can increase runtime performance, as computations that would be done at runtime are already executed at compiletime.
I believe this is a bug in libc++ which was introduced in: https://reviews.llvm.org/D41223
In particular, the _LIBCPP_CONSTEXPR_AFTER_CXX14
is missing on begin(), end(), etc.
It seems to work in libstdc++: https://godbolt.org/z/xmfdot
The bug has been reported at https://bugs.llvm.org/show_bug.cgi?id=40124 but it sounds like it may not be fixed due to difficulties obtaining a constexpr pointer to an object when one has not been constructed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With