Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In-class initialization of static data members

Tags:

c++

c++11

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.

like image 873
7cows Avatar asked May 04 '13 11:05

7cows


People also ask

How do you initialize a static data member in a class?

Static Data Member Initialization in C++ We can put static members (Functions or Variables) in C++ classes. For the static variables, we have to initialize them after defining the class. To initialize we have to use the class name then scope resolution operator, then the variable name. Now we can assign some value.

What is the correct syntax of initialization of static member?

4. Which is the correct syntax for declaring static data member? Explanation: The syntax must firstly be mentioned with the keyword static. Then the data type of the member followed by the member name should be given.

What is correct about the static data member of a class?

What is correct about the static data member of a class? A static member function can access only static data members of a class. A static data member is shared among all the object of the class.

Is a static data member it can only be initialized at its definition?

8.1: Static data. Any data member of a class can be declared static ; be it in the public or private section of the class interface. Such a data member is created and initialized only once, in contrast to non-static data members which are created again and again for each object of the class.


1 Answers

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.

like image 143
dyp Avatar answered Oct 22 '22 12:10

dyp