<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang xml:lang>
<head>
  <meta charset="utf-8" />
  <meta name="generator" content="mpark/wg21" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
  <meta name="dcterms.date" content="2025-05-17" />
  <title>Allow static data members in local and unnamed classes</title>
  <style>
      code{white-space: pre-wrap;}
      span.smallcaps{font-variant: small-caps;}
      span.underline{text-decoration: underline;}
      div.column{display: inline-block; vertical-align: top; width: 50%;}
      div.csl-block{margin-left: 1.5em;}
      ul.task-list{list-style: none;}
      pre > code.sourceCode { white-space: pre; position: relative; }
      pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
      pre > code.sourceCode > span:empty { height: 1.2em; }
      .sourceCode { overflow: visible; }
      code.sourceCode > span { color: inherit; text-decoration: inherit; }
      div.sourceCode { margin: 1em 0; }
      pre.sourceCode { margin: 0; }
      @media screen {
      div.sourceCode { overflow: auto; }
      }
      @media print {
      pre > code.sourceCode { white-space: pre-wrap; }
      pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
      }
      pre.numberSource code
        { counter-reset: source-line 0; }
      pre.numberSource code > span
        { position: relative; left: -4em; counter-increment: source-line; }
      pre.numberSource code > span > a:first-child::before
        { content: counter(source-line);
          position: relative; left: -1em; text-align: right; vertical-align: baseline;
          border: none; display: inline-block;
          -webkit-touch-callout: none; -webkit-user-select: none;
          -khtml-user-select: none; -moz-user-select: none;
          -ms-user-select: none; user-select: none;
          padding: 0 4px; width: 4em;
          color: #aaaaaa;
        }
      pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
      div.sourceCode
        {  background-color: #f6f8fa; }
      @media screen {
      pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
      }
      code span { } /* Normal */
      code span.al { color: #ff0000; } /* Alert */
      code span.an { } /* Annotation */
      code span.at { } /* Attribute */
      code span.bn { color: #9f6807; } /* BaseN */
      code span.bu { color: #9f6807; } /* BuiltIn */
      code span.cf { color: #00607c; } /* ControlFlow */
      code span.ch { color: #9f6807; } /* Char */
      code span.cn { } /* Constant */
      code span.co { color: #008000; font-style: italic; } /* Comment */
      code span.cv { color: #008000; font-style: italic; } /* CommentVar */
      code span.do { color: #008000; } /* Documentation */
      code span.dt { color: #00607c; } /* DataType */
      code span.dv { color: #9f6807; } /* DecVal */
      code span.er { color: #ff0000; font-weight: bold; } /* Error */
      code span.ex { } /* Extension */
      code span.fl { color: #9f6807; } /* Float */
      code span.fu { } /* Function */
      code span.im { } /* Import */
      code span.in { color: #008000; } /* Information */
      code span.kw { color: #00607c; } /* Keyword */
      code span.op { color: #af1915; } /* Operator */
      code span.ot { } /* Other */
      code span.pp { color: #6f4e37; } /* Preprocessor */
      code span.re { } /* RegionMarker */
      code span.sc { color: #9f6807; } /* SpecialChar */
      code span.ss { color: #9f6807; } /* SpecialString */
      code span.st { color: #9f6807; } /* String */
      code span.va { } /* Variable */
      code span.vs { color: #9f6807; } /* VerbatimString */
      code span.wa { color: #008000; font-weight: bold; } /* Warning */
      code.diff {color: #898887}
      code.diff span.va {color: #006e28}
      code.diff span.st {color: #bf0303}
  </style>
  <style type="text/css">
body {
margin: 5em;
font-family: serif;

hyphens: auto;
line-height: 1.35;
text-align: justify;
}
@media screen and (max-width: 30em) {
body {
margin: 1.5em;
}
}
div.wrapper {
max-width: 60em;
margin: auto;
}

ul {
list-style-type: none;
padding-left: 2.5em;
margin-top: -0.2em;
margin-bottom: -0.2em;
}
ol {
padding-left: 2.5em;
}
a {
text-decoration: none;
color: #4183C4;
}
a.hidden_link {
text-decoration: none;
color: inherit;
}
li {
margin-top: 0.6em;
margin-bottom: 0.6em;
}
h1, h2, h3, h4 {
position: relative;
line-height: 1;
}
a.self-link {
position: absolute;
top: 0;
left: calc(-1 * (3.5rem - 26px));
width: calc(3.5rem - 26px);
height: 2em;
text-align: center;
border: none;
transition: opacity .2s;
opacity: .5;
font-family: sans-serif;
font-weight: normal;
font-size: 83%;
}
a.self-link:hover { opacity: 1; }
a.self-link::before { content: "§"; }
ul > li:before {
content: "\2014";
position: absolute;
margin-left: -1.5em;
}

#TOC ul > li:before {
content: none;
}
#TOC > ul {
padding-left: 0;
}

.toc-section-number {
margin-right: 0.5em;
}
:target { background-color: #C9FBC9; }
:target .codeblock { background-color: #C9FBC9; }
:target ul { background-color: #C9FBC9; }
.abbr_ref { float: right; }
.folded_abbr_ref { float: right; }
:target .folded_abbr_ref { display: none; }
:target .unfolded_abbr_ref { float: right; display: inherit; }
.unfolded_abbr_ref { display: none; }
.secnum { display: inline-block; min-width: 35pt; }
.header-section-number { display: inline-block; min-width: 35pt; }
.annexnum { display: block; }
div.sourceLinkParent {
float: right;
}
a.sourceLink {
position: absolute;
opacity: 0;
margin-left: 10pt;
}
a.sourceLink:hover {
opacity: 1;
}
a.itemDeclLink {
position: absolute;
font-size: 75%;
text-align: right;
width: 5em;
opacity: 0;
}
a.itemDeclLink:hover { opacity: 1; }
span.marginalizedparent {
position: relative;
left: -5em;
}
li span.marginalizedparent { left: -7em; }
li ul > li span.marginalizedparent { left: -9em; }
li ul > li ul > li span.marginalizedparent { left: -11em; }
li ul > li ul > li ul > li span.marginalizedparent { left: -13em; }
div.footnoteNumberParent {
position: relative;
left: -4.7em;
}
a.marginalized {
position: absolute;
font-size: 75%;
text-align: right;
width: 5em;
}
a.enumerated_item_num {
position: relative;
left: -3.5em;
display: inline-block;
margin-right: -3em;
text-align: right;
width: 3em;
}
div.para { margin-bottom: 0.6em; margin-top: 0.6em; text-align: justify; }
div.section { text-align: justify; }
div.sentence { display: inline; }
span.indexparent {
display: inline;
position: relative;
float: right;
right: -1em;
}
a.index {
position: absolute;
display: none;
}
a.index:before { content: "⟵"; }

a.index:target {
display: inline;
}
.indexitems {
margin-left: 2em;
text-indent: -2em;
}
div.itemdescr {
margin-left: 3em;
}
.bnf {
font-family: serif;
margin-left: 40pt;
margin-top: 0.5em;
margin-bottom: 0.5em;
}
.ncbnf {
font-family: serif;
margin-top: 0.5em;
margin-bottom: 0.5em;
margin-left: 40pt;
}
.ncsimplebnf {
font-family: serif;
font-style: italic;
margin-top: 0.5em;
margin-bottom: 0.5em;
margin-left: 40pt;
background: inherit; 
}
span.textnormal {
font-style: normal;
font-family: serif;
white-space: normal;
display: inline-block;
}
span.rlap {
display: inline-block;
width: 0px;
}
span.descr { font-style: normal; font-family: serif; }
span.grammarterm { font-style: italic; }
span.term { font-style: italic; }
span.terminal { font-family: monospace; font-style: normal; }
span.nonterminal { font-style: italic; }
span.tcode { font-family: monospace; font-style: normal; }
span.textbf { font-weight: bold; }
span.textsc { font-variant: small-caps; }
a.nontermdef { font-style: italic; font-family: serif; }
span.emph { font-style: italic; }
span.techterm { font-style: italic; }
span.mathit { font-style: italic; }
span.mathsf { font-family: sans-serif; }
span.mathrm { font-family: serif; font-style: normal; }
span.textrm { font-family: serif; }
span.textsl { font-style: italic; }
span.mathtt { font-family: monospace; font-style: normal; }
span.mbox { font-family: serif; font-style: normal; }
span.ungap { display: inline-block; width: 2pt; }
span.textit { font-style: italic; }
span.texttt { font-family: monospace; }
span.tcode_in_codeblock { font-family: monospace; font-style: normal; }
span.phantom { color: white; }

span.math { font-style: normal; }
span.mathblock {
display: block;
margin-left: auto;
margin-right: auto;
margin-top: 1.2em;
margin-bottom: 1.2em;
text-align: center;
}
span.mathalpha {
font-style: italic;
}
span.synopsis {
font-weight: bold;
margin-top: 0.5em;
display: block;
}
span.definition {
font-weight: bold;
display: block;
}
.codeblock {
margin-left: 1.2em;
line-height: 127%;
}
.outputblock {
margin-left: 1.2em;
line-height: 127%;
}
div.itemdecl {
margin-top: 2ex;
}
code.itemdeclcode {
white-space: pre;
display: block;
}
span.textsuperscript {
vertical-align: super;
font-size: smaller;
line-height: 0;
}
.footnotenum { vertical-align: super; font-size: smaller; line-height: 0; }
.footnote {
font-size: small;
margin-left: 2em;
margin-right: 2em;
margin-top: 0.6em;
margin-bottom: 0.6em;
}
div.minipage {
display: inline-block;
margin-right: 3em;
}
div.numberedTable {
text-align: center;
margin: 2em;
}
div.figure {
text-align: center;
margin: 2em;
}
table {
border: 1px solid black;
border-collapse: collapse;
margin-left: auto;
margin-right: auto;
margin-top: 0.8em;
text-align: left;
hyphens: none; 
}
td, th {
padding-left: 1em;
padding-right: 1em;
vertical-align: top;
}
td.empty {
padding: 0px;
padding-left: 1px;
}
td.left {
text-align: left;
}
td.right {
text-align: right;
}
td.center {
text-align: center;
}
td.justify {
text-align: justify;
}
td.border {
border-left: 1px solid black;
}
tr.rowsep, td.cline {
border-top: 1px solid black;
}
tr.even, tr.odd {
border-bottom: 1px solid black;
}
tr.capsep {
border-top: 3px solid black;
border-top-style: double;
}
tr.header {
border-bottom: 3px solid black;
border-bottom-style: double;
}
th {
border-bottom: 1px solid black;
}
span.centry {
font-weight: bold;
}
div.table {
display: block;
margin-left: auto;
margin-right: auto;
text-align: center;
width: 90%;
}
span.indented {
display: block;
margin-left: 2em;
margin-bottom: 1em;
margin-top: 1em;
}
ol.enumeratea { list-style-type: none; background: inherit; }
ol.enumerate { list-style-type: none; background: inherit; }

code.sourceCode > span { display: inline; }
</style>
  <link href="data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAVoJEAN6CRADegkQAWIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wCCRAAAgkQAAIJEAACCRAAsgkQAvoJEAP+CRAD/gkQA/4JEAP+CRADAgkQALoJEAACCRAAAgkQAAP///wD///8AgkQAAIJEABSCRACSgkQA/IJEAP99PQD/dzMA/3czAP99PQD/gkQA/4JEAPyCRACUgkQAFIJEAAD///8A////AHw+AFiBQwDqgkQA/4BBAP9/PxP/uZd6/9rJtf/bybX/upd7/39AFP+AQQD/gkQA/4FDAOqAQgBc////AP///wDKklv4jlEa/3o7AP+PWC//8+3o///////////////////////z7un/kFox/35AAP+GRwD/mVYA+v///wD///8A0Zpk+NmibP+0d0T/8evj///////+/fv/1sKz/9bCs//9/fr//////+/m2/+NRwL/nloA/5xYAPj///8A////ANKaZPjRmGH/5cKh////////////k149/3UwAP91MQD/lmQ//86rhv+USg3/m1YA/5hSAP+bVgD4////AP///wDSmmT4zpJY/+/bx///////8+TV/8mLT/+TVx//gkIA/5lVAP+VTAD/x6B//7aEVv/JpH7/s39J+P///wD///8A0ppk+M6SWP/u2sf///////Pj1f/Nj1T/2KFs/8mOUv+eWhD/lEsA/8aee/+0glT/x6F7/7J8Rvj///8A////ANKaZPjRmGH/48Cf///////+/v7/2qt//82PVP/OkFX/37KJ/86siv+USg7/mVQA/5hRAP+bVgD4////AP///wDSmmT40ppk/9CVXP/69O////////7+/v/x4M//8d/P//7+/f//////9u7n/6tnJf+XUgD/nFgA+P///wD///8A0ppk+NKaZP/RmWL/1qNy//r07///////////////////////+vXw/9akdP/Wnmn/y5FY/6JfFvj///8A////ANKaZFTSmmTo0ppk/9GYYv/Ql1//5cWm//Hg0P/x4ND/5cWm/9GXYP/RmGH/0ppk/9KaZOjVnmpY////AP///wDSmmQA0ppkEtKaZI7SmmT60ppk/9CWX//OkVb/zpFW/9CWX//SmmT/0ppk/NKaZJDSmmQS0ppkAP///wD///8A0ppkANKaZADSmmQA0ppkKtKaZLrSmmT/0ppk/9KaZP/SmmT/0ppkvNKaZCrSmmQA0ppkANKaZAD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkUtKaZNzSmmTc0ppkVNKaZADSmmQA0ppkANKaZADSmmQA////AP5/AAD4HwAA4AcAAMADAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAMADAADgBwAA+B8AAP5/AAAoAAAAIAAAAEAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wCCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAAyCRACMgkQA6oJEAOqCRACQgkQAEIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wD///8A////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRABigkQA5oJEAP+CRAD/gkQA/4JEAP+CRADqgkQAZoJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAAD///8A////AP///wD///8AgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAA4gkQAwoJEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQAxIJEADyCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAP///wD///8A////AP///wCCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAWgkQAmIJEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAJyCRAAYgkQAAIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wD///8A////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAdIJEAPCCRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAPSCRAB4gkQAAIJEAACCRAAAgkQAAIJEAAD///8A////AP///wD///8AgkQAAIJEAACCRAAAgkQASoJEANKCRAD/gkQA/4JEAP+CRAD/g0YA/39AAP9zLgD/bSQA/2shAP9rIQD/bSQA/3MuAP9/PwD/g0YA/4JEAP+CRAD/gkQA/4JEAP+CRADUgkQAToJEAACCRAAAgkQAAP///wD///8A////AP///wB+PwAAgkUAIoJEAKiCRAD/gkQA/4JEAP+CRAD/hEcA/4BBAP9sIwD/dTAA/5RfKv+viF7/vp56/76ee/+wiF7/lWAr/3YxAP9sIwD/f0AA/4RHAP+CRAD/gkQA/4JEAP+CRAD/gkQArIJEACaBQwAA////AP///wD///8A////AIBCAEBzNAD6f0EA/4NFAP+CRAD/gkQA/4VIAP92MwD/bSUA/6N1Tv/ezsL/////////////////////////////////38/D/6V3Uv9uJgD/dTEA/4VJAP+CRAD/gkQA/4JEAP+BQwD/fUAA/4FDAEj///8A////AP///wD///8AzJRd5qBlKf91NgD/dDUA/4JEAP+FSQD/cy4A/3YyAP/PuKP//////////////////////////////////////////////////////9K7qP94NQD/ciwA/4VJAP+CRAD/fkEA/35BAP+LSwD/mlYA6v///wD///8A////AP///wDdpnL/4qx3/8KJUv+PUhf/cTMA/3AsAP90LgD/4dK+/////////////////////////////////////////////////////////////////+TYxf91MAD/dTIA/31CAP+GRwD/llQA/6FcAP+gWwD8////AP///wD///8A////ANGZY/LSm2X/4ap3/92mcP+wdT3/byQA/8mwj////////////////////////////////////////////////////////////////////////////+LYxv9zLgP/jUoA/59bAP+hXAD/nFgA/5xYAPL///8A////AP///wD///8A0ppk8tKaZP/RmWL/1p9q/9ubXv/XqXj////////////////////////////7+fD/vZyG/6BxS/+gcUr/vJuE//r37f//////////////////////3MOr/5dQBf+dVQD/nVkA/5xYAP+cWAD/nFgA8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/SmWP/yohJ//jo2P//////////////////////4NTG/4JDFf9lGAD/bSQA/20kAP9kGAD/fz8S/+Xb0f//////5NG9/6txN/+LOgD/m1QA/51aAP+cWAD/m1cA/5xYAP+cWADy////AP///wD///8A////ANKaZPLSmmT/0ppk/8+TWf/Unmv//v37//////////////////////+TWRr/VwsA/35AAP+ERgD/g0UA/4JGAP9lHgD/kFga/8KXX/+TRwD/jT4A/49CAP+VTQD/n10A/5xYAP+OQQD/lk4A/55cAPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/y4tO/92yiP//////////////////////8NnE/8eCQP+rcTT/ez0A/3IyAP98PgD/gEMA/5FSAP+USwD/jj8A/5lUAP+JNwD/yqV2/694Mf+HNQD/jkAA/82rf/+laBj/jT4A8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/LiUr/4byY///////////////////////gupX/0I5P/+Wuev/Lklz/l1sj/308AP+QSwD/ol0A/59aAP+aVQD/k0oA/8yoh///////+fXv/6pwO//Lp3v///////Pr4f+oay7y////AP///wD///8A////ANKaZPLSmmT/0ppk/8uJSv/hvJj//////////////////////+G7l//Jhkb/0ppk/96nc//fqXX/x4xO/6dkFP+QSQD/llEA/5xXAP+USgD/yaOA///////38uv/qG05/8ijdv//////8efb/6ZpLPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/zIxO/9yxh///////////////////////7dbA/8iEQf/Sm2X/0Zlj/9ScZv/eqHf/2KJv/7yAQf+XTgD/iToA/5lSAP+JNgD/yKFv/611LP+HNQD/jT8A/8qmeP+kZRT/jT4A8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/Pk1n/1J5q//78+//////////////////+/fv/1aFv/8iEQv/Tm2b/0ppl/9GZY//Wn2z/1pZc/9eldf/Bl2b/kUcA/4w9AP+OQAD/lUwA/59eAP+cWQD/jT8A/5ZOAP+eXADy////AP///wD///8A////ANKaZPLSmmT/0ppk/9KZY//KiEn/8d/P///////////////////////47+f/05tm/8iCP//KiEj/yohJ/8eCP//RmGH//vfy///////n1sP/rXQ7/4k4AP+TTAD/nVoA/5xYAP+cVwD/nFgA/5xYAPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/0ptl/8uLTf/aq37////////////////////////////+/fz/6c2y/961jv/etY7/6Myx//78+v//////////////////////3MWv/5xXD/+ORAD/mFQA/51ZAP+cWAD/nFgA8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/SmmT/0ppk/8mFRP/s1b//////////////////////////////////////////////////////////////////////////////+PD/0JFU/7NzMv+WUQD/kUsA/5tXAP+dWQDy////AP///wD///8A////ANKaZP/SmmT/0ppk/9KaZP/Sm2X/z5NZ/8yMT//z5NX/////////////////////////////////////////////////////////////////9Ofa/8yNUP/UmGH/36p5/8yTWv+qaSD/kksA/5ROAPz///8A////AP///wD///8A0ppk5NKaZP/SmmT/0ppk/9KaZP/TnGf/zY9T/82OUv/t1sD//////////////////////////////////////////////////////+7Yw//OkFX/zI5R/9OcZ//SmmP/26V0/9ymdf/BhUf/ol8R6P///wD///8A////AP///wDSmmQ80ppk9tKaZP/SmmT/0ppk/9KaZP/TnGj/zpFW/8qJSv/dson/8uHS//////////////////////////////////Lj0//etIv/y4lL/86QVf/TnGj/0ppk/9KaZP/RmWP/05xn/9ymdfjUnWdC////AP///wD///8A////ANKaZADSmmQc0ppkotKaZP/SmmT/0ppk/9KaZP/Tm2b/0Zli/8qJSf/NjlH/16Z3/+G8mP/myKr/5siq/+G8mP/Xp3f/zY5S/8qISf/RmGH/05tm/9KaZP/SmmT/0ppk/9KaZP/SmmSm0pljINWdaQD///8A////AP///wD///8A0ppkANKaZADSmmQA0ppkQtKaZMrSmmT/0ppk/9KaZP/SmmT/0ptl/9GYYf/Nj1P/y4lL/8qISP/KiEj/y4lK/82PU//RmGH/0ptl/9KaZP/SmmT/0ppk/9KaZP/SmmTO0ppkRtKaZADSmmQA0ppkAP///wD///8A////AP///wDSmmQA0ppkANKaZADSmmQA0ppkANKaZGzSmmTu0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmTw0ppkcNKaZADSmmQA0ppkANKaZADSmmQA////AP///wD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZBLSmmSQ0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppklNKaZBTSmmQA0ppkANKaZADSmmQA0ppkANKaZAD///8A////AP///wD///8A0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQy0ppkutKaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppkvtKaZDbSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkAP///wD///8A////AP///wDSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkXNKaZODSmmT/0ppk/9KaZP/SmmT/0ppk5NKaZGDSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA////AP///wD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkBtKaZIbSmmTo0ppk6tKaZIrSmmQK0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZAD///8A////AP/8P///+B///+AH//+AAf//AAD//AAAP/AAAA/gAAAHwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA+AAAAfwAAAP/AAAP/8AAP//gAH//+AH///4H////D//" rel="icon" />
  
  <!--[if lt IE 9]>
    <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
  <![endif]-->
</head>
<body>
<div class="wrapper">
<header id="title-block-header">
<h1 class="title" style="text-align:center">Allow static data members in
local and unnamed classes</h1>
<table style="border:none;float:right">
  <tr>
    <td>Document #:</td>
    <td>P3588R1</td>
  </tr>
  <tr>
    <td>Date:</td>
    <td>2025-05-17</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Project:</td>
    <td>Programming Language C++</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Audience:</td>
    <td>
      EWG<br>
    </td>
  </tr>
  <tr>
    <td style="vertical-align:top">Reply-to:</td>
    <td>
      Brian Bi<br>&lt;<a href="mailto:bbi10@bloomberg.net" class="email">bbi10@bloomberg.net</a>&gt;<br>
    </td>
  </tr>
</table>
</header>
<div style="clear:both">
<div id="TOC" role="doc-toc">
<h1 id="toctitle">Contents</h1>
<ul>
<li><a href="#abstract" id="toc-abstract"><span class="toc-section-number">1</span> Abstract<span></span></a></li>
<li><a href="#revision-history" id="toc-revision-history"><span class="toc-section-number">2</span> Revision history<span></span></a>
<ul>
<li><a href="#r1" id="toc-r1"><span class="toc-section-number">2.1</span> R1<span></span></a></li>
</ul></li>
<li><a href="#background" id="toc-background"><span class="toc-section-number">3</span> Background<span></span></a></li>
<li><a href="#why-this-is-useful" id="toc-why-this-is-useful"><span class="toc-section-number">4</span> Why this is
useful<span></span></a></li>
<li><a href="#proposal" id="toc-proposal"><span class="toc-section-number">5</span> Proposal<span></span></a>
<ul>
<li><a href="#summary" id="toc-summary"><span class="toc-section-number">5.1</span> Summary<span></span></a></li>
<li><a href="#initialization-order" id="toc-initialization-order"><span class="toc-section-number">5.2</span> Initialization
order<span></span></a></li>
<li><a href="#what-about-functions-that-are-never-used" id="toc-what-about-functions-that-are-never-used"><span class="toc-section-number">5.3</span> What about functions that are
never used?<span></span></a></li>
</ul></li>
<li><a href="#implementation-experience" id="toc-implementation-experience"><span class="toc-section-number">6</span> Implementation
experience<span></span></a></li>
<li><a href="#proposed-wording" id="toc-proposed-wording"><span class="toc-section-number">7</span> Proposed
wording<span></span></a></li>
<li><a href="#acknowledgements" id="toc-acknowledgements"><span class="toc-section-number">8</span>
Acknowledgements<span></span></a></li>
<li><a href="#bibliography" id="toc-bibliography"><span class="toc-section-number">9</span> References<span></span></a></li>
</ul>
</div>
<h1 data-number="1" id="abstract"><span class="header-section-number">1</span> Abstract<a href="#abstract" class="self-link"></a></h1>
<p>Local and unnamed classes (as well as classes nested within) are not
permitted to declare static data members. This restriction dates back to
C++98, when there was no way to provide a definition for such a member.
In modern C++, static data members can have inline definitions, so this
rationale is obsolete. Static data members can be useful in local
classes for the same reasons why they are useful in non-local classes,
so this paper proposes to allow them in C++29.</p>
<h1 data-number="2" id="revision-history"><span class="header-section-number">2</span> Revision history<a href="#revision-history" class="self-link"></a></h1>
<h2 data-number="2.1" id="r1"><span class="header-section-number">2.1</span> R1<a href="#r1" class="self-link"></a></h2>
<ul>
<li>Updated ship vehicle to C++29</li>
<li>Expanded discussion of initialization order, providing three
possible designs</li>
<li>Expanded discussion of implementation experience, including
discussion of bug in implementation</li>
<li>Added discussion of ordering involving complete-class contexts</li>
<li>Updated wording to account for the fact that static variable
declarations would be able to overlap under this proposal</li>
</ul>
<h1 data-number="3" id="background"><span class="header-section-number">3</span> Background<a href="#background" class="self-link"></a></h1>
<p>C++03 §[class.static.data] stated as follows:</p>
<blockquote>
<p>[…] Unnamed classes and classes contained directly or indirectly
within unnamed classes shall not contain
<code class="sourceCode cpp"><span class="kw">static</span></code> data
members. [<em>Note</em>: this is because there is no mechanism to
provide the definitions for such
<code class="sourceCode cpp"><span class="kw">static</span></code> data
members. ]</p>
<p>[…] A local class shall not have
<code class="sourceCode cpp"><span class="kw">static</span></code> data
members.</p>
</blockquote>
<p>No rationale is explicitly provided for the latter restriction.
However, we can see that “there is no mechanism to provide the
definitions” applies to static data members of local classes as well.
There was one additional possible issue, which is the need to generate
an external symbol based on the identity of the local class, but it
seems that this applies equally well to functions (<em>i.e.</em>, it
seems that a member function of a local class in an inline function
would need to have a weak external symbol since its address could be
taken), and in any case, thanks to <span class="citation" data-cites="N2657">[<a href="https://wg21.link/n2657" role="doc-biblioref">N2657</a>]</span>, unnamed and local classes became
valid template arguments from C++11 and it is certain that all
implementations can generate appropriate mangled names for local classes
and members of local and unnamed classes. There do not appear to be any
remaining technical obstacles to allowing such classes to have static
data members.</p>
<p><span class="citation" data-cites="CWG728">[<a href="https://wg21.link/cwg728" role="doc-biblioref">CWG728</a>]</span>
proposed to relax some restrictions on local classes; more specifically,
to allow them to be templates, declare member templates, declare
friends, and declare static data members. It was determined that this
was a feature request, and a paper was submitted, <span class="citation" data-cites="P2044R2">[<a href="https://wg21.link/p2044r2" role="doc-biblioref">P2044R2</a>]</span>. However, that paper addressed
only the issue of member templates. <em>This</em> paper deals only with
the simpler feature of static data members.</p>
<h1 data-number="4" id="why-this-is-useful"><span class="header-section-number">4</span> Why this is useful<a href="#why-this-is-useful" class="self-link"></a></h1>
<p>C++ entities should generally be declared in the narrowest scope in
which they are needed, which may be a single function. For example, in
Google Test, the <code class="sourceCode cpp">TEST</code> macro is used
to define a single function which then verifies some expected
properties. If a class is required only for that single test, it is
convenient to declare it as a local class. It can be desirable for such
a local class to have a static data member, such as a static data member
that tracks the number of live objects of the class.</p>
<p>Here is another example: suppose that a C++ library defines a custom
version of the tuple protocol in which a tuple-like class is expected to
declare a static data member named
<code class="sourceCode cpp">tuple_size</code>, initialized to a
compile-time constant. If a unit test needs to declare such a class and
pass it as a template argument to the component under test (which is
expecting it to be a tuple), it would be convenient to be able to scope
that class to the smallest enclosing block.</p>
<p>In the former case, the static data member would be declared <code class="sourceCode cpp"><span class="kw">static</span> <span class="kw">inline</span></code>.
In the latter case, it would be declared <code class="sourceCode cpp"><span class="kw">static</span> <span class="kw">constexpr</span></code>,
which makes it implicitly inline. A non-inline static data member in a
local class cannot be defined, but I see no reason not to also allow it.
It could be used just for its type (<em>i.e.</em>, in unevaluated
contexts only). Allowing such a variable to inhabit class scope would
make it more narrowly scoped than if it were a local
<code class="sourceCode cpp"><span class="kw">extern</span></code>
variable inhabiting the enclosing function.</p>
<p>Note that although the current language does not permit static data
members in local classes, it does permit static local variables in
member functions of local classes. That is, the Meyer singleton pattern
can be contained within an outer block scope. This workaround for the
inability to declare static data members in local classes adds verbosity
in requiring a function to be defined and called. Meyer singletons also
trade off some performance for safety: additional instructions are
executed every time the function containing the static local variable is
called (unless the variable is constant-initialized), but most cases of
initialization order bugs are prevented. Although the additional safety
is useful, having to incur changes in performance as a cost of moving
static variables within a block scope violates the C++ design principle
that <em>you don’t pay for what you don’t use</em>.</p>
<h1 data-number="5" id="proposal"><span class="header-section-number">5</span> Proposal<a href="#proposal" class="self-link"></a></h1>
<h2 data-number="5.1" id="summary"><span class="header-section-number">5.1</span> Summary<a href="#summary" class="self-link"></a></h2>
<p>Allow static data members to be declared by local and unnamed classes
without restriction, except unnamed classes that have a typedef name for
linkage purposes. That is, the following would remain ill formed:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">typedef</span> <span class="kw">struct</span> <span class="op">{</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">inline</span> <span class="kw">static</span> <span class="dt">int</span> x <span class="op">=</span> <span class="dv">0</span>;</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span> S;</span></code></pre></div>
<p>§<span>9.2.4
<a href="https://wg21.link/N5008#dcl.typedef">[dcl.typedef]</a><a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a></span>p5 places various restrictions
on such classes in the vein of requiring them to be “C-like”: for
example, they can’t have member functions nor member typedefs. Since
static data members don’t exist in C, I don’t propose to drop this
restriction.</p>
<p>Likewise, restrictions on anonymous unions (§<span>11.5.2
<a href="https://wg21.link/N5008#class.union.anon">[class.union.anon]</a></span>p1)
are left untouched by this proposal. Being a compatibility feature with
C, they aren’t allowed to declare any members other than public
non-static data members.</p>
<p>Note that static data members may be thread-local, and therefore
thread-local data members will also become allowed in local classes
under this proposal. However, the current Standard doesn’t specify
initialization order for thread-local namespace-scope variables (<span class="citation" data-cites="CWG2914">[<a href="https://wg21.link/cwg2914" role="doc-biblioref">CWG2914</a>]</span>, <span class="citation" data-cites="CWG2928">[<a href="https://wg21.link/cwg2928" role="doc-biblioref">CWG2928</a>]</span>). The intent of this proposal
is to be orthogonal to those Core issues: just as static data members of
local classes are to be initialized in the same time as if they were at
namespace scope, the same is meant to hold for thread-local members of
local classes.</p>
<h2 data-number="5.2" id="initialization-order"><span class="header-section-number">5.2</span> Initialization order<a href="#initialization-order" class="self-link"></a></h2>
<p>I propose that static data members of local classes follow the same
initialization order rules as if their classes were non-local: for
example, if <code class="sourceCode cpp">x</code>,
<code class="sourceCode cpp">y</code>, and
<code class="sourceCode cpp">z</code> are three inline variables and in
every translation unit they appear in that order, and
<code class="sourceCode cpp">x</code> and
<code class="sourceCode cpp">z</code> belong to non-local classes while
<code class="sourceCode cpp">y</code> belongs to a local class, then
<code class="sourceCode cpp">y</code> is initialized after
<code class="sourceCode cpp">x</code> and before
<code class="sourceCode cpp">z</code>, unless
<code class="sourceCode cpp">y</code>’s enclosing function is templated,
in which case <code class="sourceCode cpp">y</code> could be initialized
in any order relative to <code class="sourceCode cpp">x</code> and
<code class="sourceCode cpp">z</code>. I believe that this rule is
intuitive and any other rule would be a source of bugs: if a
later-initialized static variable could be visible at the point of
declaration of an earlier-initialized one, the earlier-initialized
variable could use the later-initialized variable’s value before the
latter has been initialized.</p>
<p>It is worth noting that lexical initialization order conflicts with a
principle of C++ classes, that their behavior should not change
depending on the location of the class’s complete-class contexts.
Consider the following example:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> C <span class="op">{</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> f<span class="op">()</span>;</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">static</span> <span class="kw">inline</span> <span class="dt">int</span> a <span class="op">=</span> f<span class="op">()</span>;  <span class="co">// `b` is declared later and not yet initialized</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> C<span class="op">::</span>f<span class="op">()</span> <span class="op">{</span></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">struct</span> S <span class="op">{</span></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a>        <span class="kw">static</span> <span class="kw">inline</span> <span class="dt">int</span> b <span class="op">=</span> <span class="dv">1</span>;</span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span>;</span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> S<span class="op">::</span>b;</span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Here, <code class="sourceCode cpp">a</code> would be initialized
prior to <code class="sourceCode cpp">b</code>;
<code class="sourceCode cpp">f</code> would return either 0 or 1 (see
§<span>6.9.3.2
<a href="https://wg21.link/N5008#basic.start.static">[basic.start.static]</a></span>p3).</p>
<p>Evidently, lexical initialization order can’t prevent all
initialization order bugs, but the alternative, namely to guarantee that
static data members of class <code class="sourceCode cpp">C</code> are
initialized before static data members appearing within complete-class
contexts of <code class="sourceCode cpp">C</code>, would result in a
similar bug when <code class="sourceCode cpp">f</code> is defined in
line:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> C <span class="op">{</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>    <span class="dt">void</span> f<span class="op">()</span> <span class="op">{</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>        <span class="kw">struct</span> S <span class="op">{</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>            <span class="kw">static</span> <span class="kw">inline</span> <span class="dt">int</span> b <span class="op">=</span> <span class="dv">1</span>;</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span>;</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">static</span> <span class="kw">inline</span> <span class="dt">int</span> a <span class="op">=</span> f<span class="op">()</span>;  <span class="co">// `b` is declared in `f` and not yet initialized</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
<p>Given that neither initialization order rule is perfect, I still
advocate lexical order as the easiest to understand. A third alternative
that avoids initialization order issues completely, but reduces the
usefulness of the feature, is to require static data members of local
classes to be constant-initialized and have constant destruction.<a href="#fn2" class="footnote-ref" id="fnref2" role="doc-noteref"><sup>2</sup></a></p>
<p>To summarize, the three options are</p>
<ol type="1">
<li>Non-templated non-local static variables (including data members of
local classes) are initialized in lexical declaration order;</li>
<li>Non-templated non-local static variables are initialized in
declaration order, considering declarations appearing in complete-class
contexts of any class to follow those appearing in
non-complete-class-contexts of that class;</li>
<li>All static data members of local classes must be
constant-initialized and have constant destruction.</li>
</ol>
<h2 data-number="5.3" id="what-about-functions-that-are-never-used"><span class="header-section-number">5.3</span> What about functions that are
never used?<a href="#what-about-functions-that-are-never-used" class="self-link"></a></h2>
<p>If a function with internal or no linkage is never called and never
has its address taken, implementations can currently skip code
generation for the function. However, since I propose that the
initialization of a static data member of a local class should occur as
described in §<span>6.9.3
<a href="https://wg21.link/N5008#basic.start">[basic.start]</a></span>
(<em>i.e.</em> upon program or thread startup, unless deferred) it would
be surprising if such an initialization having side effects could be
skipped if the enclosing function isn’t called. Therefore, if there are
any static data members defined inside the function, code generation
must be done for those static data members and potentially for lambdas
reachable from them.<a href="#fn3" class="footnote-ref" id="fnref3" role="doc-noteref"><sup>3</sup></a></p>
<p>Note that for a local class, the definition of each member is always
be instantiated eagerly when the enclosing function is instantiated; see
Note 3 to §<span>13.9.2
<a href="https://wg21.link/N5008#temp.inst">[temp.inst]</a></span>p2. I
don’t propose any carve-out to this rule for static data members.</p>
<h1 data-number="6" id="implementation-experience"><span class="header-section-number">6</span> Implementation experience<a href="#implementation-experience" class="self-link"></a></h1>
<p>GCC supports static data members in unnamed and local classes as an
extension when
<code class="sourceCode cpp"><span class="op">-</span>fpermissive</code>
is used. GCC does not allow such members to be explicitly declared
<code class="sourceCode cpp"><span class="kw">inline</span></code>, but
this seems to be an oversight: the error message says “‘inline’
specifier invalid for variable ‘x’ declared at block scope”. GCC does
allow the member to be
<code class="sourceCode cpp"><span class="kw">constexpr</span></code>,
and generates an appropriate definition in that case (<em>i.e.</em>, the
address can be taken).</p>
<p>I implemented this feature partially, including dynamic
initialization of inline static data members, as
<a href="https://github.com/t3nsor/llvm-project/tree/p3588">a patch</a>
to Clang 20 (May 4, 2025). This implementation passes the Clang unit
tests but has the following known bugs:</p>
<ol type="1">
<li><p>The initialization order is not correct; complete-class contexts
are parsed later than the rest of the enclosing class, so the order in
which static data member initializers are emitted corresponds to option
2 above, rather than option 1.</p></li>
<li><p>Static data members of local classes are currently not emitted in
cases such as</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="co">// x appears at namespace scope</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> x <span class="op">=</span> <span class="op">[]</span> <span class="op">{</span> <span class="kw">struct</span> S <span class="op">{</span> <span class="kw">static</span> <span class="kw">inline</span> <span class="dt">int</span> y <span class="op">=</span> <span class="dv">0</span>; <span class="op">}</span>; <span class="cf">return</span> S<span class="op">::</span>y; <span class="op">}()</span>;</span></code></pre></div>
<p>because the code that iterates over definitions to emit them misses
closure types that were injected into the enclosing namespace scope. (As
a result, a program containing the above translation unit fails to
link.)</p></li>
</ol>
<p>In order to ensure lexical initialization order, it seems that an
implementation might need to store the location of each non-templated
static data member found while parsing a top-level class definition
(<em>i.e.</em>, one that does not have any enclosing class scope) and
then sort them at the end of the class definition. This would be novel
but not extremely difficult to implement. Such lists (of which multiple
might be produced for every namespace-scope declaration) could also be
used to fix the second bug.</p>
<h1 data-number="7" id="proposed-wording"><span class="header-section-number">7</span> Proposed wording<a href="#proposed-wording" class="self-link"></a></h1>
<p>Wording is relative to <span class="citation" data-cites="N5008">[<a href="https://wg21.link/n5008" role="doc-biblioref">N5008</a>]</span>.</p>
<p>Modify §<span>6.9.3.3
<a href="https://wg21.link/N5008#basic.start.dynamic">[basic.start.dynamic]</a></span>p2
as follows to account for the fact that a definition of a static data
member of a local class can be nested within the definition of some
other variable requiring dynamic initialization.</p>
<blockquote>
<p><span class="add" style="color: #006e28"><ins>For two definitions
<span><code class="sourceCode default">D</code></span> and
<span><code class="sourceCode default">E</code></span> of non-block
variables with static storage duration,</ins></span><span class="rm" style="color: #bf0303"><del>A declaration</del></span>
<code class="sourceCode cpp">D</code> is <em>appearance-ordered</em>
before <span class="rm" style="color: #bf0303"><del>a
declaration</del></span> <code class="sourceCode cpp">E</code> if</p>
<ul>
<li><code class="sourceCode cpp">D</code> appears in the same
translation unit as <code class="sourceCode cpp">E</code>, or</li>
<li>the translation unit containing
<code class="sourceCode cpp">E</code> has an interface dependency on the
translation unit containing <code class="sourceCode cpp">D</code>,</li>
</ul>
<p><span class="add" style="color: #006e28"><ins>and</ins></span> <span class="rm" style="color: #bf0303"><del>in either case prior
to</del></span><span class="add" style="color: #006e28"><ins>the
<em>init-declarator</em> of
<span><code class="sourceCode default">D</code></span> ends before the
<em>init-declarator</em> of</ins></span>
<code class="sourceCode cpp">E</code>.</p>
</blockquote>
<p>Strike §<span>11.4.9.3
<a href="https://wg21.link/N5008#class.static.data">[class.static.data]</a></span>p2.
(The first sentence is redundant with §<span>9.2.2
<a href="https://wg21.link/N5008#dcl.stc">[dcl.stc]</a></span>p8.)</p>
<blockquote>
<p><span class="rm" style="color: #bf0303"><del>A static data member
shall not be
<span><code class="sourceCode default">mutable</code></span>
([dcl.stc]). A static data member shall not be a direct member
([class.mem]) of an unnamed ([class.pre]) or local ([class.local]) class
or of a (possibly indirectly) nested class ([class.nest])
thereof.</del></span></p>
</blockquote>
<p>Strike §<span>11.6
<a href="https://wg21.link/N5008#class.local">[class.local]</a></span>p4.</p>
<blockquote>
<p><span class="rm" style="color: #bf0303"><del>[<em>Note 2</em>: A
local class cannot have static data members ([class.static.data]).
— <em>end note</em>]</del></span></p>
</blockquote>
<h1 data-number="8" id="acknowledgements"><span class="header-section-number">8</span> Acknowledgements<a href="#acknowledgements" class="self-link"></a></h1>
<p>Bengt Gustafsson, Arthur O’Dwyer, and Corentin Jabot provided
valuable feedback on the motivation, wording, and implementation for
this paper.</p>
<h1 data-number="9" id="bibliography"><span class="header-section-number">9</span> References<a href="#bibliography" class="self-link"></a></h1>
<div id="refs" class="references csl-bib-body hanging-indent" data-entry-spacing="1" role="doc-bibliography">
<div id="ref-CWG2914" class="csl-entry" role="doc-biblioentry">
[CWG2914] Brian Bi. 2024-06-20. Unclear order of initialization of
static and thread-local variables. <a href="https://wg21.link/cwg2914"><div class="csl-block">https://wg21.link/cwg2914</div></a>
</div>
<div id="ref-CWG2928" class="csl-entry" role="doc-biblioentry">
[CWG2928] CWG. 2024-08-16. No ordering for initializing thread-local
variables. <a href="https://wg21.link/cwg2928"><div class="csl-block">https://wg21.link/cwg2928</div></a>
</div>
<div id="ref-CWG728" class="csl-entry" role="doc-biblioentry">
[CWG728] Faisal Vali. 2008-10-05. Restrictions on local classes. <a href="https://wg21.link/cwg728"><div class="csl-block">https://wg21.link/cwg728</div></a>
</div>
<div id="ref-N2657" class="csl-entry" role="doc-biblioentry">
[N2657] John Spicer. 2008-06-10. Local and Unnamed Types as Template
Arguments. <a href="https://wg21.link/n2657"><div class="csl-block">https://wg21.link/n2657</div></a>
</div>
<div id="ref-N5008" class="csl-entry" role="doc-biblioentry">
[N5008] Thomas Köppe. 2025-03-15. Working Draft, Programming Languages —
C++. <a href="https://wg21.link/n5008"><div class="csl-block">https://wg21.link/n5008</div></a>
</div>
<div id="ref-P2044R2" class="csl-entry" role="doc-biblioentry">
[P2044R2] Robert Leahy. 2020-04-14. Member Templates for Local Classes.
<a href="https://wg21.link/p2044r2"><div class="csl-block">https://wg21.link/p2044r2</div></a>
</div>
</div>
<section class="footnotes footnotes-end-of-document" role="doc-endnotes">
<hr />
<ol>
<li id="fn1" role="doc-endnote"><p>All citations to the Standard are to
working draft N5008 unless otherwise specified.<a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn2" role="doc-endnote"><p>All
<code class="sourceCode cpp"><span class="kw">constexpr</span></code>
static variable declarations would necessarily satisfy this criterion,
but there are others that would as well, such as the example of an
instance counter, defined as <code class="sourceCode cpp"><span class="kw">static</span> <span class="kw">inline</span> <span class="dt">int</span> count <span class="op">=</span> <span class="dv">0</span>;</code>;
the destruction of <code class="sourceCode cpp">count</code> itself is
trivial.<a href="#fnref2" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn3" role="doc-endnote"><p>If the behavior of my (partial)
implementation exhibits any deviation from these rules, the deviation is
unintentional.<a href="#fnref3" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>
</div>
</div>
</body>
</html>
