Title
Order of initialization of multiply-defined static data members of class templates
Status
nad
Section
6.9.3.2 [basic.start.static]
Submitter
Andrei Iltchenko

Created on 2001-02-08.00:00:00 last changed 281 months ago

Messages

Date: 2001-10-15.00:00:00

Notes from 10/01 meeting:

It was decided that this issue is not linked to issue 270 and that there is no problem, because there is only one instantiation (see 5.2 [lex.phases] paragraph 8).

Date: 2022-09-25.18:08:42

According to 6.3 [basic.def.odr] paragraph 5, it is possible for a static data member of a class template to be defined more than once in a given program provided that each such definition occurs in a different translation unit and the ODR is met.

Now consider the following example:

src1.cpp:

    #include <iostream>

    int  initializer()
    {
       static int   counter;
       return  counter++;
    }

    int   g_data1 = initializer();

    template<class T>
    struct  exp  {
       static int   m_data;
    };
    template<class T>
    int  exp<T>::m_data = initializer();

    int   g_data2 = initializer();
    extern int   g_data3;

    int  main()
    {
       std::cout << exp<char>::m_data << ", " << g_data1 << ", "
	  << g_data2 << ", " << g_data3 << std::endl;
       return  0;
    }

src2.cpp:

    extern int  initializer();
    int  g_data3 = initializer();

    template<class T>
    struct  exp  {
       static int   m_data;
    };
    template<class T>
    int  exp<T>::m_data = initializer();

    void  func()
    {
      exp<char>::m_data++;
    }

The specialization exp<char>::m_data is implicitly instaniated in both translation units, hence (13.9.2 [temp.inst] paragraph 1) its initialization occurs. And for both definitions of exp<T>::m_data the ODR is met. According to 6.9.3.2 [basic.start.static] paragraph 1:

Objects with static storage duration defined in namespace scope in the same translation unit and dynamically initialized shall be initialized in the order in which their definition appears in the translation unit.

But for exp<T>::m_data we have two definitions. Does it mean that both g_data1 and g_data3 are guaranteed to be dynamically initialized before exp<char>::m_data?

Suggested Resolution: Insert the following sentence before the last two sentences of 6.3 [basic.def.odr] paragraph 5:

In the case of D being a static data member of a class template the following shall also hold:

  • for a given (not explicit) specialization of D initialized dynamically (6.9.3.2 [basic.start.static]), the accumulated set of objects initialized dynamically in namespace scope before the specialization of D shall be the same in every translation unit that contains the definition for this specialization.
History
Date User Action Args
2001-11-09 00:00:00adminsetstatus: review -> nad
2001-05-20 00:00:00adminsetmessages: + msg480
2001-05-20 00:00:00adminsetstatus: open -> review
2001-02-08 00:00:00admincreate