{"id":5944,"date":"2020-07-11T08:32:03","date_gmt":"2020-07-11T08:32:03","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/c-20-static-initialization-order-fiasco\/"},"modified":"2023-06-26T09:47:23","modified_gmt":"2023-06-26T09:47:23","slug":"c-20-static-initialization-order-fiasco","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/c-20-static-initialization-order-fiasco\/","title":{"rendered":"Solving the Static Initialization Order Fiasco with C++20"},"content":{"rendered":"<p>According to the <a href=\"https:\/\/isocpp.org\/wiki\/faq\/ctors#static-init-order\">FAQ of isocpp.org<\/a>&nbsp;is the static initialization order fiasco &#8220;<em>a subtle way to crash your program&#8221;.&nbsp;<\/em>The FAQ continues<em>: The static initialization order problem is a very subtle and commonly misunderstood aspect of C++.&nbsp;<\/em>&#8220;. Today, I write about this very subtle and misunderstood aspect of C++.&nbsp;&nbsp;<span style=\"color: #333333; font-family: 'Crimson Text', 'Times New Roman', serif; font-size: 17px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; float: none;\"><br \/><\/span><\/p>\n<p><!--more--><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5199\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/TimelineCpp20.png\" alt=\"TimelineCpp20\" width=\"650\" height=\"234\" style=\"display: block; margin-left: auto; margin-right: auto;\" \/><\/p>\n<h2>My short Disclaimer<\/h2>\n<p>Before I continue, I want to make a short disclaimer. Today&#8217;s post is about variables with static storage duration and their dependencies. Variables with static storage duration may be global (namespace) variables, static variables, or static class members. In short, I call them static variables. <strong>Dependencies on static variables in different translation units are generally a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Code_smell\">code smell<\/a> and should be a reason for refactoring.<\/strong> Consequently, if you follow my advice to refactor, you can skip the rest of this post.&nbsp;<\/p>\n<\/p>\n<h2>Static Initialization Order Fiasco<\/h2>\n<p>Static variables in one translation unit are initialized according to their definition order.<\/p>\n<p>In contrast, the initialization of static variables between translation units has a severe issue. When one static variable <span style=\"font-family: courier new, courier;\">staticA<\/span> is defined in one translation unit and another static variable <span style=\"font-family: courier new, courier;\">staticB<\/span> is defined in another, and <span style=\"font-family: courier new, courier;\">staticB<\/span>&nbsp;needs <span style=\"font-family: courier new, courier;\">staticA<\/span>&nbsp;to initialize itself, you end with the static initialization order fiasco. The program is ill-formed because you have no guarantee which static variable is initialized first at run-time (dynamic).<\/p>\n<p>Before discussing the rescue, let me show you the static initialization order fiasco.<\/p>\n<h3>A 50:50 Chance to get it Right<\/h3>\n<p>What is unique about the initialization of static variables? The initialization of static variables happens in two steps: static and dynamic.&nbsp;<\/p>\n<p>When a static cannot be <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/constant_initialization\">const-initialized<\/a> during compile-time, it is <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/zero_initialization\">zero-initialized<\/a>. At run-time, the dynamic initialization happens for these statics that is <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/zero_initialization\">zero-initialized<\/a> at compile-time.&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ sourceSIOF1.cpp<\/span>\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">quad<\/span>(<span style=\"color: #007788; font-weight: bold;\">int<\/span> n) {\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> n <span style=\"color: #555555;\">*<\/span> n;\r\n}\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">auto<\/span> staticA  <span style=\"color: #555555;\">=<\/span> quad(<span style=\"color: #ff6600;\">5<\/span>); \r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ mainSOIF1.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">extern<\/span> <span style=\"color: #007788; font-weight: bold;\">int<\/span> staticA;   <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">auto<\/span> staticB <span style=\"color: #555555;\">=<\/span> staticA;\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>() {\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"staticB: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> staticB <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    \r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Line (1) declares the static variable <span style=\"font-family: 'courier new', courier;\">staticA<\/span>.&nbsp;The initialization of <span style=\"font-family: 'courier new', courier;\">staticB<\/span> depends on the initialization of <span style=\"font-family: 'courier new', courier;\">staticA<\/span>. <span style=\"font-family: 'courier new', courier;\">staticB<\/span> is zero-initialized at compile-time and dynamically initialized at run-time. The issue is that there is no guarantee in which order&nbsp;<span style=\"font-family: 'courier new', courier;\">staticA<\/span> or <span style=\"font-family: 'courier new', courier;\">staticB <\/span>are initialized.<span style=\"font-family: 'courier new', courier;\"> staticA <\/span>and<span style=\"font-family: 'courier new', courier;\"> staticB<\/span>&nbsp;belong to different translation units. You have a 50:50 chance that <span style=\"font-family: 'courier new', courier;\">staticB<\/span> is 0 or 25.&nbsp;<\/p>\n<p>To make my observation visible, I change the link order of the object files. This also changes the value for <span style=\"font-family: 'courier new', courier;\">staticB!<\/span><\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5941\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/07\/StaticInitializationOrderFiasco.png\" alt=\"StaticInitializationOrderFiasco\" width=\"500\" height=\"282\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/07\/StaticInitializationOrderFiasco.png 686w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/07\/StaticInitializationOrderFiasco-300x169.png 300w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/p>\n<p>What a fiasco!&nbsp; The result of the executable depends on the link order of the object files. What can we do when we don&#8217;t have C++20 at our disposal?&nbsp;<\/p>\n<h3>Lazy Initialization of static with local scope<\/h3>\n<p>Static variables with the local scope are created when used for the first time. Local scope essentially means that the static variable is surrounded in some way by curly braces. This lazy creation is a guarantee that C++98 provides. With C++11, static variables with the local scope are also initialized in a thread-safe way. The thread-safe Meyers Singleton is based on this additional guarantee. I already wrote a post about the &#8220;<a href=\"https:\/\/www.modernescpp.com\/index.php\/thread-safe-initialization-of-a-singleton\">Thread-Safe Initialization of a Singleton<\/a>&#8220;.&nbsp;<\/p>\n<p>Lazy initialization can also be used to overcome the static initialization order fiasco.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ sourceSIOF2.cpp<\/span>\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">quad<\/span>(<span style=\"color: #007788; font-weight: bold;\">int<\/span> n) {\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> n <span style=\"color: #555555;\">*<\/span> n;\r\n}\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&amp;<\/span> staticA() {\r\n    \r\n    <span style=\"color: #006699; font-weight: bold;\">static<\/span> <span style=\"color: #006699; font-weight: bold;\">auto<\/span> staticA  <span style=\"color: #555555;\">=<\/span> quad(<span style=\"color: #ff6600;\">5<\/span>);   <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> staticA;\r\n    \r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ mainSOIF2.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&amp;<\/span> staticA();           <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">auto<\/span> staticB <span style=\"color: #555555;\">=<\/span> staticA(); <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>() {\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"staticB: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> staticB <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    \r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p><span style=\"font-family: 'courier new', courier;\">staticA<\/span> is, in this case, static in a local scope (1). Line (2) declares the function <span style=\"font-family: 'courier new', courier;\">staticA<\/span>, which is used to initialize in the following line <span style=\"font-family: 'courier new', courier;\">staticB<\/span>. This local scope of <span style=\"font-family: 'courier new', courier;\">staticA<\/span> guarantees that <span style=\"font-family: 'courier new', courier;\">staticA<\/span> is created and initialized during run-time when it is the first time used. Changing the link order can, in this case, not change the value of <span style=\"font-family: 'courier new', courier;\">staticB.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5942\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/07\/StaticInitializationOrderFiascoMeyers.png\" alt=\"StaticInitializationOrderFiascoMeyers\" width=\"500\" height=\"282\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/07\/StaticInitializationOrderFiascoMeyers.png 686w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/07\/StaticInitializationOrderFiascoMeyers-300x169.png 300w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/p>\n<p>Now, I solve the static initialization order fiasco using C++20.<\/p>\n<h3>Compile-time initialization of a static<\/h3>\n<p>Let me apply <span style=\"font-family: 'courier new', courier;\">constinit<\/span> to <span style=\"font-family: 'courier new', courier;\">staticA<\/span>. <span style=\"font-family: 'courier new', courier;\">constinit<\/span> guarantees that <span style=\"font-family: 'courier new', courier;\">staticA<\/span> is initialized during compile-time.<\/p>\n<p>&nbsp;<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ sourceSIOF3.cpp<\/span>\r\n\r\nconstexpr <span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">quad<\/span>(<span style=\"color: #007788; font-weight: bold;\">int<\/span> n) {\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> n <span style=\"color: #555555;\">*<\/span> n;\r\n}\r\n\r\nconstinit <span style=\"color: #006699; font-weight: bold;\">auto<\/span> staticA  <span style=\"color: #555555;\">=<\/span> quad(<span style=\"color: #ff6600;\">5<\/span>);  <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ mainSOIF3.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">extern<\/span> constinit <span style=\"color: #007788; font-weight: bold;\">int<\/span> staticA;     <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">auto<\/span> staticB <span style=\"color: #555555;\">=<\/span> staticA;\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>() {\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"staticB: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> staticB <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    \r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>(1) declares the variable <span style=\"font-family: 'courier new', courier;\">staticA<\/span>. <span style=\"font-family: 'courier new', courier;\">staticA<\/span>&nbsp;(2) is initialized during compile-time. By the way, using <span style=\"font-family: 'courier new', courier;\">constexpr<\/span> in (1) instead of <span style=\"font-family: 'courier new', courier;\">constinit<\/span> is not valid because <span style=\"font-family: 'courier new', courier;\">constexpr<\/span> requires a definition and not just a declaration.&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>Thanks to Clang 10 compiler, I can execute the program.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5943\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/07\/StaticInitializationOrderFiascoConstinit.png\" alt=\"StaticInitializationOrderFiascoConstinit\" width=\"500\" height=\"294\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/07\/StaticInitializationOrderFiascoConstinit.png 2072w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/07\/StaticInitializationOrderFiascoConstinit-300x177.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/07\/StaticInitializationOrderFiascoConstinit-1024x603.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/07\/StaticInitializationOrderFiascoConstinit-768x452.png 768w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/07\/StaticInitializationOrderFiascoConstinit-1536x904.png 1536w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/07\/StaticInitializationOrderFiascoConstinit-2048x1206.png 2048w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/p>\n<p>As in the case of the lazy initialization with a local static, <span style=\"font-family: 'courier new', courier;\">staticB<\/span> has the value 25.<\/p>\n<h2 style=\"color: #000000;\">What&#8217;s next?<\/h2>\n<p>C++20 has a few small improvements around Templates and Lambdas. In my<a href=\"https:\/\/www.modernescpp.com\/index.php\/template-improvements-with-c-20\"> next post,<\/a> I will present which ones.<\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>According to the FAQ of isocpp.org&nbsp;is the static initialization order fiasco &#8220;a subtle way to crash your program&#8221;.&nbsp;The FAQ continues: The static initialization order problem is a very subtle and commonly misunderstood aspect of C++.&nbsp;&#8220;. Today, I write about this very subtle and misunderstood aspect of C++.&nbsp;&nbsp;<\/p>\n","protected":false},"author":21,"featured_media":5199,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[375],"tags":[461,460],"class_list":["post-5944","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-c-20","tag-constinit","tag-initialization"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5944","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/comments?post=5944"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5944\/revisions"}],"predecessor-version":[{"id":6733,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5944\/revisions\/6733"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5199"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5944"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5944"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5944"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}