<p>Document Number: P0421R0<br />
Audience: Evolution Working Group (EWG)<br />
Author: Mariusz Moczala &lt;<a href="mailto:mmoczala@gmail.com">mmoczala@gmail.com</a>&gt;<br />
Date: 2016-09-14</p>

<h1>Static class constructor</h1>

<h2 id="content">1. Content</h2>
<p><a href="#content">1. Content</a><br />
<a href="#abstract">2. Abstract</a><br />
<a href="#motivation">3. Motivation</a><br />
<a href="#impact_on_the_standard">4. Impact On the Standard</a><br />
<a href="#design_decisions">5. Design Decisions</a><br />
<a href="#declaration_and_definition">5.1. Declaration and definition</a><br />
<a href="#parameters">5.2. Parameters</a><br />
<a href="#this_pointer">5.3. This pointer</a><br />
<a href="#execution_order">5.4. Execution order</a><br />
<a href="#inheritance">5.5. Inheritance</a><br />
<a href="#initializer_list">5.6. Initializer list</a><br />
<a href="#one_definition_rule">5.7. One Definition Rule</a><br />
<a href="#auto_generation">5.8. Auto generation</a><br />
<a href="#local_classes">5.9. Local classes</a><br />
<a href="#static_destructor">5.10. Static destructor</a><br />
<a href="#static_inline_variables">6. Static inline variables</a><br />
<a href="#references">7. References</a></p>

<h2 id="abstract">2. Abstract</h2>
<p>As a class constructor is dedicated for object initialization, proposed static class constructor offers type registration. When class defines static class constructor, it code is executed once, early before <i>main()</i> function execution. As usual static member function, static class constructor have no associated object and has access to all the static members of the class.</p>

<h2 id="motivation">3. Motivation</h2>
<p>Static class constructor allows execution of class code, without calling it from outside the class body. This feature provides flexible and object oriented way to register new functionality of an application. Currently it can be achieved through creation of dummy global variable, where default class constructor of that variable performs additional code for such registration. Nevertheless, without static class constructor, this cannot be achieved in header-only code. Please refer to <a href="#design_decisions">Design Decisions</a> for example usage. The static class constructors offers:</p>

<p><ul>
<li>consistent and object oriented mechanism for type registration</li>
<li>static member initialization through initializer list of static class constructor</li>
<li>execution of class code without calling it directly from outside the class body</li>
</ul></p>

<h2 id="impact_on_the_standard">4. Impact On the Standard</h2>
<p>This proposal adds new language feature which affects a compiler only.</p>
<p>The feature is backward compatible as classes does not has to provide a definition of static class constructor. When class defines a static class constructor, used syntax is identical with declaration and definition of default class constructor, except that the static class constructor name is preceded by <i>static</i> keyword.</p>
<p>Static class constructor is executed once for each class defining such constructor. It happens exactly in the same manner as for constructors of objects defined at global scope. Both are always executed before execution of <i>main()</i> function. Program startup code uses the same mechanism to execute both, constructors of global variables, and static class constructors. For static class constructors pointer to associated object can be undefined or set to <i>NULL</i>, as <i>this</i> keyword is not available for static class constructors.</p>
<p>Static class variables can be initialized on member initializer list of static class constructor. Therefore, when single header is used for multiple translation units, One Definition Rule must be meet.</p>

<h2 id="design_decisions">5. Design Decisions</h2>
<p>For better clarification, please consider the following code using a static class constructor:</p>
<pre>class MyPlugin : public Plugin {
  public:
    static MyPlugin() {
      static MyPlugin myPlugin;
      Plugins::registerPlugin(&amp;myPlugin);
    }
    ~MyPlugin() {
      Plugins::unregisterPlugin(this);
    }
};</pre>
<p>Which is equivalent to the following, when defined at global scope:</p>
<pre>class MyPlugin : public Plugin {
  public:
    MyPlugin() {
      Plugins::registerPlugin(this);
    }
    ~MyPlugin() {
      Plugins::unregisterPlugin(this);
    }
} myPlugin;</pre>
<p>The equivalent code have some pitfalls which can be avoided with static class constructor:</p>
<p><ul>
<li>There is no need to create dummy global variable to perform initialization.</li>
<li>Each dummy global variable used in initialization have associated identifier and therefore is visible under IntelliSense. It becomes more difficult in navigation for projects using multiple dummy global variables.</li>
<li>Static constructors allows to perform early initialization for headers-only libraries, where global variables cannot easily be used.</li>
</ul></p>

<h3 id="declaration_and_definition">5.1. Declaration and definition</h3>
<p>Class does not have to provide a declaration nor definition of static class constructor. When class defines a static class constructor, used syntax is identical with declaration and definition of default class constructor, except that the static class constructor name is preceded by static keyword.</p>

<h3 id="parameters">5.2. Parameters</h3>
<p>The static class constructor is called once by program startup code. It cannot be executed manually and its address cannot be obtained. It does not take any arguments as in case of default class constructor.</p>

<h3 id="this_pointer">5.3. This pointer</h3>
<p>The static class constructor is not associated with an object as other static class functions. Therefore <i>this</i> pointer is not available for static class constructors.</p>

<h3 id="execution_order">5.4. Execution order</h3>
<p>Static class constructors are executed one by one among execution of class constructors for variables defined at global scope in order of consecutive definitions occurring in translation unit.</p>

<h3 id="inheritance">5.5. Inheritance</h3>
<p>Static class constructors are inherited exactly in the same manner as in case of default class constructors. Consecutive actions are taken in following order:</p>
<p><ul>
<li>execution of static class constructors of base classes in order form the top most class,</li>
<li>initialization of static members not defined through the initializer list,</li>
<li>initialization of static members defined through the initializer list,</li>
<li>execution of static class constructor code.</li>
</ul></p>

<h3 id="initializer_list">5.6. Initializer list</h3>
<p>The static class constructor is a good place to provide initialization of static class members. It can be achieved through initializer list as for non-static class member initialization on non-static class constructor initializer list.</p>

<h3 id="one_definition_rule">5.7. One Definition Rule</h3>
<p>When single header is used for multiple translation units, One Definition Rule must be meet to avoid static member redefinition.</p>

<h3 id="auto_generation">5.8. Auto generation</h3>
<p>The static class constructor can initialize static class members through initializer list as non-static members are initialized through class constructor. However in case when default class constructor is not defined for class, object members are initialized with its default constructors. This cannot be achieved for static class constructor, to be backward compatible. Therefore, if static class constructor is not defined, static class member variable must be defined outside the class body as usual. Otherwise, when static class constructor is defined, all static members not defined through initializer list will be initialized with its default constructors, even if they are not defined outside the class body.</p>

<h3 id="local_classes">5.9. Local classes</h3>
<p>There is no distinction between static class constructors defined for classes at global and local scope.</p>

<h3 id="static_destructor">5.10. Static class destructor</h3>
<p>A static class destructor was also considered on early proposal stage. It could however work in similar way to static class constructor, but to perform type deregistration. It has been found that introducing such functionality can be simply replaced with classical destructor, as static class constructor allow to create a static object, which will be destroyed on process termination.</p>
<p>Nevertheless it would be very useful to have a static class destructor along with static class constructor, as it may open new possibilities which were not so obviously visible at the time when this document was created.</p>

<h3 id="static_inline_variables">6. Static inline variables</h3>
<p>The static class constructor offers similar features to static inline variables proposed for C++17 standard. However both proposals are not excluding each other. As static inline variables are dedicated for static class member initialization, achieving early initialization functionality through static inline variables is more difficult and have more complicated syntax. In this case static class constructor is more reasonable.</p>

<h3 id="references">7. References</h3>
<p><ul>
<li>ISO C++ Standard (ISO/IEC 14882) 2003, section 3.2.</li>
<li>Hal Finkel and Richard Smith, Inline Variables, 20150407, N4424, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4424.pdf">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4424.pdf</a></li>
</ul></p>
