title: Is storing initializer_lists undefined behaviour?
body: <p>This question is a follow up to <a href="https://stackoverflow.com/questions/72377360/how-come-stdinitializer-list-is-allowed-to-not-specify-size-and-be-stack-alloc">How come std::initializer_list is allowed to not specify size AND be stack allocated at the same time?</a></p>
  <p>The short answer was that calling a function with brace-enclosed list <code>foo({2, 3, 4, 5, 6});</code> conceptually creates a temporary array in the stackspace before the call and then passes the initializer list which (like string_view) just references this local temporary array (probably in registers):</p>
  <pre><code>int __tmp_arr[5] {2, 3, 4, 5, 6};
  foo(std::initializer_list{arr, arr + 5});
  </code></pre>
  <p>Now consider the following case where I have nested initializer_lists of an object &quot;ref&quot;. This ref object stores primitives types or an initializer_list recursively in a variant. My question now is: Is this undefined behaviour? It appears to work with my code, but does it hold up to the standard? My reason for doubting is that when the inner constructor calls for the nested brace-enclosed lists return, the temporary array which the initializer list is refering to could be invalidated because the stack pointer is reset (thus saving the initializer_list in the variant preserves an invalid object). Writing to subsequent memory would then overwrite values refered to by the initializer list. Am I wrong in believing that?</p>
  <p><a href="https://godbolt.org/#z:OYLghAFBqd5QCxAYwPYBMCmBRdBLAF1QCcAaPECAMzwBtMA7AQwFtMQByARg9KtQYEAysib0QXACx8BBAKoBnTAAUAHpwAMvAFYTStJg1DIApACYAQuYukl9ZATwDKjdAGFUtAK4sGIM6SuADJ4DJgAcj4ARpjEIAAcpAAOqAqETgwe3r7%2ByanpAiFhkSwxcYl2mA4ZQgRMxARZPn4BldUCtfUERRHRsQm2dQ1NOa1D3aG9pf3xAJS2qF7EyOwc5gDMocjeWADUJutuAG71eIYEB9gmGgCCG1s7mPuHCgTEocAA%2Bkd4mADul2udzMmwY2y8ewObmQr3wqEBtyBXjSRl2J1ozwAIrtYSAQCd3ucobiQCwBKk6gRMKRdqECDSoqhPDSSa93kZvr8/iyCOg8aF0mI8AAvWKfWh4V7Et5eBy7YiYKiA9ZXdZWRG3NmygjyxVAkwAdnVN12pt1VAgjM8swOxrN5ogdJtaqB9oVFrQDFeu2QCHqACpnXaze6ICSBY4haLiOLJRdDu7LkH9bd7ei0WIvJhPrb9QbMbmNTctXLPXVJsQ88HTWWmBWw7z%2BQxBRLo7GpQm9Srac2CLN9kbXfazUl2QQLeYzABaGezufzhcmACsbgYk%2BTqeHptHdPbBEdvY3JrNhoLRbTqDw6F2O8Ee4bfJAEbOrbFEo7bkT3fffaHpsN1bDvwxC7BAnreomZgAGzyrsIC7D%2B/YAX%2BW5mngVCgSSCCeOgCifGIVLEMwjhHJg0qPmSDAUkwVKXBAxAAHTolmnyzEhg6bqhqG3uOECTnSy6ruuhbHlx/75rsmC0EotIYQ%2BeLYbQuH4bQhHEXgpFQgJKr0UxmbZmxA6AWJI5jhOZhmAJK5rhZR4meJ2JSTJ6GYY2ICKcpBGxOpmmHFatB0YxzEGexxn2Tx5lmP5gk2WYdn2aeknSU8Lnye5OF4V5RE0RpZEvG5bIfJy/yBXp3ghUZKH2TeZl8RZhUcj8JXWcJLqcWJiVOSlclYRlKlqTlvluOGvYviKb5xlCX6qtgunBaxoVVeFtX8aNUYTa8IAxa1YUmTx94ksAmDxsNbnPutMY/lNXYzXN%2BkLSJ1WnktDkoc9iL5iJQLunioZ0j2hD9vB80ARGiUATVdKReYS7Xq8JCYOg20WTSEZBgOZ43D9IChv5AN9nBGblTmRpgxJEMRXVZgwwoOJEAqSMtSj%2BPPAAYvsFkymRFmE5OVBiEoO0Y99iq/YqYECN6voBvjQNEyxAGsm8RVNQCpO9s95NGpDgjQ2YS60/DDPIwEsu2sLtzY6GI0tuNl2TZ2SrdmjhMg%2BrhDg9rlOrbbbY/nTCOM0JzNo%2Bb713Lc/0sHWDAQDaH2AbWFY4qgbCfEnYQgQc2IQ1wNJczSS40hDyEWYQmAsMCpvU/mxeDmXVIsFYzNc5rBafW1dz5hw8y0JwS68H4HBaKQqCcG41jWCnSwrBz6w8KQBCaD38wANYgEuGj6JwkiD8vo%2BcLwCggFvS/Dz3pBwLAMCICgqdJHQsTkJQaAsA/9BxMACjMEkCjYfSNBVKxGPpafeURQj1AAJ6cAXq/NgggADyDBaDQPPqQLA0cjDiDQfgBU1RSLHzQZgVQVQvBUn3nSKS%2B8JRRGIFAjwWB97KxYDAi%2BVADBfwAGpcgQUkRgrCZCCBEGIdgUhBHyCUGofeug84GCMCgSelh9B4CiMfSA8xUBJEcJLTgM5YTZ1MJYawXADRHyklUbRfgICuBGH4POwRJglDKHoFIaRLG2JcfkSxPQnH9Dzm0SxnRhieGaHoAJNRxg%2BL6HEfx4wPGxK6FE6YMT5gKEWMsURi8FSrB4L3fue80Fjw4KoeIUEpxQUkLsYAyBkCgRlAwVe/YIATyMUo3YuBCAkDnnnXYHg36PyziCLgsxeBny0GxUg69N7bw4LvUgLDJDrAYusJcBp1hQRWZIMwayACckgi5DxHkUo%2BJ9F7L3mFfW%2BiwCBJDIc/CW/SP7hFYKsEpZSKk%2BjkcAOpxAvANJGYEfA9Mrx6H4EI0Q4gxFgokSodQaCZGkD%2BHQpIrC8kcAHqQQ5vAikILIbcnUqAMJvPKZU6ptSID1MaaBPp79YjdIBWMlepAECYCYFgOIccZlzJYUuKCDEKnQXWfsg00ENBLgOfvY5thTmMomVMrefcODrAKUcw%2BZzz4TMVWYFV2K1WyvmKRYgaRnCSCAA%3D%3D%3D" rel="nofollow noreferrer">CompilerExplorer</a></p>
  <pre><code>#include &lt;variant&gt;
  #include &lt;string_view&gt;
  #include &lt;type_traits&gt;
  #include &lt;cstdio&gt;
  
  using val = std::variant&lt;std::monostate, int, bool, std::string_view, std::initializer_list&lt;struct ref&gt;&gt;;
  
  struct ref
  {
      ref(bool);
      ref(int);
      ref(const char*);
      ref(std::initializer_list&lt;ref&gt;);
  
      val value_;
  };
  
  struct container
  {
      container(std::initializer_list&lt;ref&gt; init) {
          printf(&quot;---------------------\n&quot;);
          print_list(init);
      }
  
      void print_list(std::initializer_list&lt;ref&gt; list)
      {
          for (const ref&amp; r : list) {
              if (std::holds_alternative&lt;std::monostate&gt;(r.value_)) {
                  printf(&quot;int\n&quot;);
              } else if (std::holds_alternative&lt;int&gt;(r.value_)) {
                  printf(&quot;int\n&quot;);
              } else if (std::holds_alternative&lt;bool&gt;(r.value_)) {
                  printf(&quot;bool\n&quot;);
              } else if (std::holds_alternative&lt;std::string_view&gt;(r.value_)) {
                  printf(&quot;string_view\n&quot;);
              } else if (std::holds_alternative&lt;std::initializer_list&lt;ref&gt;&gt;(r.value_)) {
                  printf(&quot;initializer_list:\n&quot;);
                  print_list(std::get&lt;std::initializer_list&lt;ref&gt;&gt;(r.value_));
              }
          }
      }
  };
  
  ref::ref(int init) : value_{init} { printf(&quot;%d stored\n&quot;, init); }
  ref::ref(bool init) : value_{init} { printf(&quot;%s stored\n&quot;, init ? &quot;true&quot; : &quot;false&quot;); }
  ref::ref(const char* init) : value_{std::string_view{init}} { printf(&quot;%s stored\n&quot;, init); }
  ref::ref(std::initializer_list&lt;ref&gt; init) : value_{init} { printf(&quot;initializer_list stored\n&quot;, init); }
  
  int main()
  {
      container some_container = { 1, true, 5, { {&quot;itemA&quot;, 2}, {&quot;itemB&quot;, true}}};
  }
  </code></pre>
  <p>Output:</p>
  <pre><code>1 stored
  true stored
  5 stored
  itemA stored
  2 stored
  initializer_list stored
  itemB stored
  true stored
  initializer_list stored
  initializer_list stored
  ---------------------
  int
  bool
  int
  initializer_list:
  initializer_list:
  string_view
  int
  initializer_list:
  string_view
  bool
  </code></pre>