In-class initialization of static data members

c++, c++11

Solution

Why can there be an initializer in the class definition?

Concerning the two exceptions for `const` and `constexpr` static data members:

[class.static.data]/3

[ Note: In both these cases, the member may appear in constant expressions. — end note ]

I.e. with an initializer, you may use them in constant expressions, e.g.

struct s
{
    static std::size_t const len = 10;
    int arr[len];
};
std::size_t const s::len;

If `len` wasn't initialized in the class definition, the compiler couldn't easily know its value in the next line to define the length of `arr`.

One could argue about allowing initializers for of non-`const`, non-`constexpr` static data members in the class definition, but this could interfere with the initialization order:

[basic.start.init]/2

Definitions of explicitly specialized class template static data members have ordered initialization. Other class template static data members (i.e., implicitly or explicitly instantiated specializations) have unordered initialization. Other non-local variables with static storage duration have ordered initialization.

That is, the order of the definitions including initializers is important. The order of (dynamic) initialization of non-local objects is only defined within a translation unit, this is another reason why there has to be a definition including initializer for non-`const`, non-`constexpr` static data members.

What's the point of this extra definition?

This has already been answered in the comments IMO. You might want to add the ODR, that is, as a name with external linkage, the static data member must (only) be defined in one translation unit (if it's ODR-used). It's up to the programmer to choose this translation unit.

Problem

In C++, `static` members may not be initialized in the class body with these exceptions: - `static` members of `const` integral type can be - `static` members of `constexpr` literal type must be Can you explain why these exceptions? Also, this holds: Even if a `const static` data member is initialized in the class body, that member ordinarily should be defined outside the class definition. This I never understood at all. What's the point of this extra definition? Just trying to get some intuitions here.

Original source