Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <blockquote> <p>Within the same compilation unit, the C++ standard says that static initialization order is well defined -- it's the order of the declarations of the static objects.</p> </blockquote> <p>In your shown code you have no declaration of a static data member. You have a declaration of a typedef-name. These have nothing to do with that, and don't influence any order. <em>You probably think along this way</em>:</p> <blockquote> <p>If i make that typedef declaration, it will instantiate <code>helper&lt;int&gt;</code>, and thus instantiate its static data member declaration first.</p> </blockquote> <p>The problem is, that line does not cause an instantiation of <code>helper&lt;int&gt;</code>. For that to happen, you would need an explicit instantiation or manage to make it instantiate it implicitly (creating an object of <code>helper&lt;int&gt;</code> for example, or using it as a nested name specifier as in <code>helper&lt;int&gt;::...</code> and explicitly referencing the static member - otherwise, creation of it is omitted). </p> <p>But there is a much deeper problem. The order is <em>not</em> the declaration of the static data-members. The order is <em>their definition</em>. Consider the following</p> <pre><code>struct C { C() { printf("hey\n"); } }; struct A { static C a; static C b; }; C A::b; C A::a; </code></pre> <p>In this code, <strong>b is created before a</strong>, even though <strong>a is declared before b</strong>. </p> <p>The following code prints <code>2 1</code>:</p> <pre><code>struct C { C(int n) { printf("%d\n", n); } }; template&lt;int N&gt; struct A { static C c; }; template&lt;int N&gt; C A&lt;N&gt;::c(N); // explicit instantiation of declaration and definition template struct A&lt;2&gt;; template struct A&lt;1&gt;; int main() { } </code></pre> <p>But the following code prints nothing, unless you comment in the line in <code>main</code>.</p> <pre><code>struct C { C(int n) { printf("%d\n", n); } }; template&lt;int N&gt; struct A { static C c; }; template&lt;int N&gt; C A&lt;N&gt;::c(N); // implicit instantiation of declarations A&lt;2&gt; a2; A&lt;1&gt; a1; int main() { // A&lt;1&gt;::c; A&lt;2&gt;::c; } </code></pre> <p>I'm not actually sure what the correct output for this second snippet is. Reading the Standard, i can't determine an order. It says at <code>14.6.4.1</code> "Point of Instantiation":</p> <blockquote> <p>For a function template specialization, a member function template specialization, or a specialization for a member function or static data member of a class template, if the specialization is implicitly instantiated because it is referenced from within another template specialization [...]. Otherwise, the point of instantiation for such a specialization immediately follows the namespace scope declaration or definition that refers to the specialization.</p> </blockquote> <p>The point of instantiation of their definitions both appear immediately after the definition of <code>main</code>. Which definition is instantiated before the other definition seems to be left unspecified. If anyone knows the answer and khow other compilers behave (GCC prints <code>1 2</code> but with the order of the expressions in <code>main</code> swapped, prints <code>2 1</code>), please let me know in the comment.</p> <p>For details, see <a href="https://stackoverflow.com/questions/1079623/what-is-the-lifetime-of-class-static-variables-in-c/1080211#1080211">this answer about static object's lifetime</a>.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload