4

In C++03, we had the ability to initialize const static class data members inline within the class definition, but still had to define the member if it were to be odr-used.

Is this still the case in C++11?

struct Foo
{
   static const int x = 3;
};

const int Foo::x;
// ^ required?
Community
  • 1
  • 1
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055

1 Answers1

8

Yes.

[C++11: 9.4.2/3]: If a non-volatile const static data member is of integral or enumeration type, its declaration in the class definition can specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression (5.19). A static data member of literal type can be declared in the class definition with the constexpr specifier; if so, its declaration shall specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression. [ Note: In both these cases, the member may appear in constant expressions. —end note ] The member shall still be defined in a namespace scope if it is odr-used (3.2) in the program and the namespace scope definition shall not contain an initializer.

This is comparable to the wording in C++03:

[C++03: 9.4.2/2]: If a static data member is of const integral or const enumeration type, its declaration in the class definition can specify a constant-initializer which shall be an integral constant expression (5.19). In that case, the member can appear in integral constant expressions. The member shall still be defined in a namespace scope if it is used in the program and the namespace scope definition shall not contain an initializer.

As you can see, the rule itself hasn't changed at all, beyond the introduction of rules for constexpr.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • There was also a change in the definition of odr-used, which can impact which members are required to be defined. – Dave S Apr 24 '13 at 11:32
  • 1
    @DaveS: Good point. Alas, the respective definitions of _odr-used_ in both (actually C++03 calls it "potentially evaluated") is too complex to be injected into this answer. :( – Lightness Races in Orbit Apr 24 '13 at 11:36