I'm not sure if this is a compiler bug or if I misunderstand constexpr:
struct S{};
constexpr S s1{};
constexpr S s2;
struct test{
static constexpr auto t1 = s1;
static constexpr auto t2 = s2; //error here
};
GCC 4.8 is giving me an odd error "error: field initializer is not constant". Is s2 really not a constant? If so why?
For clarity I actually am using a bunch of empty structs in my code (for meta programming https://github.com/porkybrain/Kvasir) so I really am interested in this specific example.
The keyword constexpr was introduced in C++11 and improved in C++14. It means constant expression. Like const , it can be applied to variables: A compiler error is raised when any code attempts to modify the value.
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.
A non-static data member cannot be constexpr. static constexpr int x = 5; int y; };
const can only be used with non-static member functions whereas constexpr can be used with member and non-member functions, even with constructors but with condition that argument and return type must be of literal types.
Update: The code should compile, because [class.ctor]/5
reads:
The implicitly-defined default constructor performs the set of initializations of the class that would be performed by a user-written default constructor for that class with no ctor-initializer (12.6.2) and an empty compound-statement. If that user-written default constructor would satisfy the requirements of a
constexpr
constructor (7.1.5), the implicitly-defined default constructor isconstexpr
.
And since S
is just an empty struct, the implicitly defined default constructor is empty and thus satisfying constexpr
requirements.
So here you are dealing with imperfection of the compilers, which you have to workaround somehow.
Old answer:
Clang emits more sensible error message:
main.cpp:3:13: error: default initialization of an object of const type 'const S'
requires a user-provided default constructor
constexpr S s2;
^
[dcl.constexpr]/9 provides the explanation and even almost exactly your code as an example:
A
constexpr
specifier used in an object declaration declares the object as const. Such an object shall have literal type and shall be initialized.(...) [ Example:
struct pixel {
int x, y;
};
constexpr pixel ur = { 1294, 1024 };// OK
constexpr pixel origin; // error: initializer missing
—end example ]
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