How do I forward-declare a constexpr object at nam

2019-04-24 04:30发布

问题:

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?

回答1:

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.



回答2:

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.