On clang (trunk) I can forward declare an object that will later be defined with constexpr
as follows:
// Fwd-declarations
struct S;
extern const S s;
// (... later) definitions
struct S {};
constexpr S s {};
Gcc 4.8 doesn't like this, telling me the forward-declaration and the definition differ in constexpr
-ness. Is gcc speaking truth, or is this just a gcc bug?
I can't find any language in my copy of the C++11 standard that explicitly forbids constexpr
-ness from mis-matching between a declaration and a definition, but I do see language explicitly forbidding constexpr
from being used with extern
(section 7.1.5), and I also see language requiring the initializer for a class-level static
constexpr
variable to be in the class. Also, since the utility of constexpr
is significantly reduced when the definition of the variable or its type is unavailable, I think it's likely the intent is that constexpr
variables must be defined (or, for static
class members, initialized) when they are declared.
As a work-around, perhaps you could provide an extern
alias for the variable. This would allow you to take its address, and that's the only thing I can think of that a forward-declaration would allow. For example:
// .hpp file:
struct C;
extern C const &c;
// .cpp file:
struct C {
constexpr C() { }
};
constexpr C cc;
C const &c = cc;
Side note: I know that in C++14, they revisited/are revisiting constexpr
, so it's possible that it works in Clang because it's implementing some draft spec of C++14.
The real answer is that gcc is plain wrong, clang is right. The code above should compile, and it will in gcc 4.9. Or so says this bug report.