I tried to forward-declare a constexpr
variable template like this:
template<typename>
constexpr std::size_t iterator_category_value;
The goal was to document that every specialization should be constexpr
but I have to admit that I never checked whether it was legal or not and g++ was happy with it. However, when I tried to compile this spinnet with clang++ instead, I got the following error:
error: default initialization of an object of const type 'const std::size_t' (aka 'const unsigned long') constexpr std::size_t iterator_category_value; ^ = 0
The error makes sense, and removing constexpr
makes it disappear, so that's not a real problem. However, I am curious now: does the standard allow such a constexpr
forward declaration for a variable template or is it illegal? g++ and clang++ seem to disagree and I would like to know where I should submit a bug report if needed.
Both of them complain for a forward-declared constepxr
variable which is not a variable template, so the variable template context seems to be what makes the compilers disagree.
Although constexpr variables can be given external linkage via the extern keyword, they can not be forward declared, so there is no value in giving them external linkage. This is because the compiler needs to know the value of the constexpr variable (at compile time).
Constexpr functions are implicitly inline, which means they are suitable to be defined in header files. Like any function in a header, the compiler is more likely to inline it than other functions.
In the C++14 standard, it seems pretty clear that initialization is required. From section 7.5.1 paragraph 9,
A
constexpr
specifier used in an object declaration declares the object as const. Such an object shall have literal type and shall be initialized.
As for the exact meaning of "object declaration", Section 7 paragraph 7 states:
If the decl-specifier-seq contains no typedef specifier, the declaration is called a function declaration if the type associated with the name is a function type and an object declaration otherwise.
Clang is correct. The declaration of a variable template is an object declaration ([dcl.dcl]/9), hence it must provide an initializer as per [dcl.constexpr]/9:
A
constexpr
specifier used in an object declaration declares the object asconst
. Such an object […] shall be initialized.
There is effectively no way of "forward" declaring an object as constexpr
in the first place, though; If constexpr
is applied to the declaration of a variable, it shall be a definition ([dcl.constexpr]/1).
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