<!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="2024-02-13" />
  <title>std::uninitialized&lt;T&gt;</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.hanging-indent{margin-left: 1.5em; text-indent: -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; }
      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;
}
div.wrapper {
max-width: 60em;
margin: auto;
}
ul {
list-style-type: none;
padding-left: 2em;
margin-top: -0.2em;
margin-bottom: -0.2em;
}
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;
}
: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>
  <style type="text/css">a {
color : #4183C4;
text-decoration: underline;
}
a.marginalized {
text-decoration: none;
}
a.self-link {
text-decoration: none;
}
h1#toctitle {
border-bottom: 1px solid #cccccc;
}
#TOC li {
margin-top: 1px;
margin-bottom: 1px;
}
#TOC ul>li:before { display: none; }
h3.subtitle { margin-top: -15px; }
h1:target { background-color: transparent; }
h2:target { background-color: transparent; }
h3:target { background-color: transparent; }
h4:target { background-color: transparent; }
h5:target { background-color: transparent; }
h6:target { background-color: transparent; }
code span.co { font-family: monospace; }
table tr {
background-color: white;
}
table tr:nth-child(2n) {
background-color: #f6f8fa;
}
#title-block-header > table tr:nth-child(2n) {
background-color: white;
}
td > div.sourceCode {
background-color: inherit;
}
table {
border-collapse: collapse;
}
table td, table th {
border: 1px solid #cccccc;
}
table th {
border-bottom: 1px solid black;
text-align: center;
}
table tr:first-child th {
border-top: 0;
}
table tr:last-child td {
border-bottom: 0;
}
table tr td:first-child,
table tr th:first-child {
border-left: 0;
}
table tr td:last-child,
table tr th:last-child {
border-right: 0;
}
table tbody tr:first-child td {
border-top: 1px solid black;
}
#title-block-header td { border: 0; }
@media all {
body {
margin: 2em;
}
}
@media screen and (min-width: 480px) {
body {
margin: 5em;
}
}
#refs code{padding-left: 0px; text-indent: 0px;}
:root {
--diff-ins: #e6ffed;
--diff-strongins: #acf2bd;
--diff-del: #ffdddd;
--diff-strongdel: #ff8888;
}
span.diffins {
background-color: var(--diff-strongins);
}
span.diffdel {
background-color: var(--diff-strongdel);
}
div.rm { text-decoration: line-through; }
div.rm code.sourceCode { text-decoration: line-through; }
div.addu, span.addu {
color: #006e28;
background-color: var(--diff-ins);
}

div.rm pre, div.add pre { background-color: #f6f8fa; }
div.addu pre { background-color: var(--diff-ins); }
div.add, div.add pre { background-color: var(--diff-ins); }
div.addu blockquote {
border-left: 4px solid #00a000;
padding: 0 15px;
color: #006e28;
text-decoration: none;
}
div.addu blockquote code.sourceCode { text-decoration: none; }
div.addu blockquote pre { text-decoration: none; }
div.addu blockquote pre code { text-decoration: none; }
div.quote {
border-left: 7px solid #ccc;
background: #f9f9f9;
margin: 1.5em 10px;
padding-left: 20px;
}
code.diff span.va { color: #000000; background-color: var(--diff-ins); }
code.diff span.st { color: #000000; background-color: var(--diff-del); }
</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"><code class="sourceCode cpp">std<span class="op">::</span>uninitialized<span class="op">&lt;</span>T<span class="op">&gt;</span></code></h1>

<table style="border:none;float:right">
  <tr>
    <td>Document #:</td>
    <td>P3074R2</td>
  </tr>
  <tr>
    <td>Date:</td>
    <td>2024-02-13</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>
      Barry Revzin<br>&lt;<a href="mailto:barry.revzin@gmail.com" class="email">barry.revzin@gmail.com</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="#revision-history"><span class="toc-section-number">1</span> Revision History<span></span></a></li>
<li><a href="#introduction"><span class="toc-section-number">2</span> Introduction<span></span></a>
<ul>
<li><a href="#the-uninitialized-storage-problem"><span class="toc-section-number">2.1</span> The uninitialized storage problem<span></span></a></li>
</ul></li>
<li><a href="#design-space"><span class="toc-section-number">3</span> Design Space<span></span></a>
<ul>
<li><a href="#a-library-type-stduninitializedt"><span class="toc-section-number">3.1</span> A library type: <code class="sourceCode cpp">std<span class="op">::</span>uninitialized<span class="op">&lt;</span>T<span class="op">&gt;</span></code><span></span></a></li>
<li><a href="#a-language-annotation"><span class="toc-section-number">3.2</span> A language annotation<span></span></a></li>
<li><a href="#existing-practice"><span class="toc-section-number">3.3</span> Existing Practice<span></span></a></li>
</ul></li>
<li><a href="#wording"><span class="toc-section-number">4</span> Wording<span></span></a></li>
<li><a href="#bibliography"><span class="toc-section-number">5</span> References<span></span></a></li>
</ul>
</div>
<h1 data-number="1" style="border-bottom:1px solid #cccccc" id="revision-history"><span class="header-section-number">1</span> Revision History<a href="#revision-history" class="self-link"></a></h1>
<p><span class="citation" data-cites="P3074R0">[<a href="#ref-P3074R0" role="doc-biblioref">P3074R0</a>]</span> originally proposed the function <code class="sourceCode cpp">std<span class="op">::</span>start_lifetime<span class="op">(</span>p<span class="op">)</span></code>. This revision adds a new section discussing the <a href="#the-uninitialized-storage-problem">uninitialized storage problem</a>, which motivates a change in design to instead propose <code class="sourceCode cpp">std<span class="op">::</span>uninitialized<span class="op">&lt;</span>T<span class="op">&gt;</span></code>.</p>
<p><span class="citation" data-cites="P3074R1">[<a href="#ref-P3074R1" role="doc-biblioref">P3074R1</a>]</span> changed to propose <code class="sourceCode cpp">std<span class="op">::</span>uninitialized<span class="op">&lt;</span>T<span class="op">&gt;</span></code> and was discussed in an EWG telecon. There, the suggestion was made to make this a language feature, which this revision discusses and argues against. Also re-spelled <code class="sourceCode cpp">std<span class="op">::</span>uninitialized<span class="op">&lt;</span>T<span class="op">&gt;</span></code> to be a union instead of a class containing an anonymous union.</p>
<h1 data-number="2" style="border-bottom:1px solid #cccccc" id="introduction"><span class="header-section-number">2</span> Introduction<a href="#introduction" class="self-link"></a></h1>
<p>Consider the following example:</p>
<blockquote>
<div class="sourceCode" id="cb1"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb1-1"><a href="#cb1-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T, <span class="dt">size_t</span> N<span class="op">&gt;</span></span>
<span id="cb1-2"><a href="#cb1-2"></a><span class="kw">struct</span> FixedVector <span class="op">{</span></span>
<span id="cb1-3"><a href="#cb1-3"></a>    <span class="kw">union</span> U <span class="op">{</span> <span class="kw">constexpr</span> U<span class="op">()</span> <span class="op">{</span> <span class="op">}</span> <span class="kw">constexpr</span> <span class="op">~</span>U<span class="op">()</span> <span class="op">{</span> <span class="op">}</span> T storage<span class="op">[</span>N<span class="op">]</span>; <span class="op">}</span>;</span>
<span id="cb1-4"><a href="#cb1-4"></a>    U u;</span>
<span id="cb1-5"><a href="#cb1-5"></a>    <span class="dt">size_t</span> size <span class="op">=</span> <span class="dv">0</span>;</span>
<span id="cb1-6"><a href="#cb1-6"></a></span>
<span id="cb1-7"><a href="#cb1-7"></a>    <span class="co">// note: we are *not* constructing storage</span></span>
<span id="cb1-8"><a href="#cb1-8"></a>    <span class="kw">constexpr</span> FixedVector<span class="op">()</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb1-9"><a href="#cb1-9"></a></span>
<span id="cb1-10"><a href="#cb1-10"></a>    <span class="kw">constexpr</span> <span class="op">~</span>FixedVector<span class="op">()</span> <span class="op">{</span></span>
<span id="cb1-11"><a href="#cb1-11"></a>        std<span class="op">::</span>destroy<span class="op">(</span>u<span class="op">.</span>storage, u<span class="op">.</span>storage<span class="op">+</span>size<span class="op">)</span>;</span>
<span id="cb1-12"><a href="#cb1-12"></a>    <span class="op">}</span></span>
<span id="cb1-13"><a href="#cb1-13"></a></span>
<span id="cb1-14"><a href="#cb1-14"></a>    <span class="kw">constexpr</span> <span class="kw">auto</span> push_back<span class="op">(</span>T <span class="kw">const</span><span class="op">&amp;</span> v<span class="op">)</span> <span class="op">-&gt;</span> <span class="dt">void</span> <span class="op">{</span></span>
<span id="cb1-15"><a href="#cb1-15"></a>        std<span class="op">::</span>construct_at<span class="op">(</span>u<span class="op">.</span>storage <span class="op">+</span> size, v<span class="op">)</span>;</span>
<span id="cb1-16"><a href="#cb1-16"></a>        <span class="op">++</span>size;</span>
<span id="cb1-17"><a href="#cb1-17"></a>    <span class="op">}</span></span>
<span id="cb1-18"><a href="#cb1-18"></a><span class="op">}</span>;</span>
<span id="cb1-19"><a href="#cb1-19"></a></span>
<span id="cb1-20"><a href="#cb1-20"></a><span class="kw">constexpr</span> <span class="kw">auto</span> silly_test<span class="op">()</span> <span class="op">-&gt;</span> <span class="dt">size_t</span> <span class="op">{</span></span>
<span id="cb1-21"><a href="#cb1-21"></a>    FixedVector<span class="op">&lt;</span>std<span class="op">::</span>string, <span class="dv">3</span><span class="op">&gt;</span> v;</span>
<span id="cb1-22"><a href="#cb1-22"></a>    v<span class="op">.</span>push_back<span class="op">(</span><span class="st">&quot;some sufficiently longer string&quot;</span><span class="op">)</span>;</span>
<span id="cb1-23"><a href="#cb1-23"></a>    <span class="cf">return</span> v<span class="op">.</span>size;</span>
<span id="cb1-24"><a href="#cb1-24"></a><span class="op">}</span></span>
<span id="cb1-25"><a href="#cb1-25"></a><span class="kw">static_assert</span><span class="op">(</span>silly_test<span class="op">()</span> <span class="op">==</span> <span class="dv">1</span><span class="op">)</span>;</span></code></pre></div>
</blockquote>
<p>This is basically how any static/non-allocating/in-place vector is implemented: we have some storage, that we <em>definitely do not value initialize</em> and then we steadily construct elements into it.</p>
<p>The problem is that the above does not work (although there is <a href="https://godbolt.org/z/a3318n63v">implementation divergence</a> - MSVC and EDG accept it and GCC did accept it even up to 13.2, but GCC trunk and Clang reject).</p>
<p>Getting this example to work would allow <code class="sourceCode cpp">std<span class="op">::</span>inplace_vector</code> (<span class="citation" data-cites="P0843R9">[<a href="#ref-P0843R9" role="doc-biblioref">P0843R9</a>]</span>) to simply work during <code class="sourceCode cpp"><span class="kw">constexpr</span></code> time for all times (instead of just trivial ones), and was a problem briefly touched on in <span class="citation" data-cites="P2747R0">[<a href="#ref-P2747R0" role="doc-biblioref">P2747R0</a>]</span>.</p>
<h2 data-number="2.1" id="the-uninitialized-storage-problem"><span class="header-section-number">2.1</span> The uninitialized storage problem<a href="#the-uninitialized-storage-problem" class="self-link"></a></h2>
<p>A closely related problem to the above is: how do you do uninitialized storage? The straightforward implementation would be to do:</p>
<blockquote>
<div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T<span class="op">&gt;</span></span>
<span id="cb2-2"><a href="#cb2-2"></a><span class="kw">struct</span> BufferStorage <span class="op">{</span></span>
<span id="cb2-3"><a href="#cb2-3"></a><span class="kw">private</span><span class="op">:</span></span>
<span id="cb2-4"><a href="#cb2-4"></a>    <span class="kw">alignas</span><span class="op">(</span>T<span class="op">)</span> <span class="dt">unsigned</span> <span class="dt">char</span> buffer<span class="op">[</span><span class="kw">sizeof</span><span class="op">(</span>T<span class="op">)]</span>;</span>
<span id="cb2-5"><a href="#cb2-5"></a></span>
<span id="cb2-6"><a href="#cb2-6"></a><span class="kw">public</span><span class="op">:</span></span>
<span id="cb2-7"><a href="#cb2-7"></a>    <span class="co">// accessors</span></span>
<span id="cb2-8"><a href="#cb2-8"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
<p>This approach generally works, but it has two limitations:</p>
<ol type="1">
<li>it cannot work in <code class="sourceCode cpp"><span class="kw">constexpr</span></code> and that’s likely a fundamental limitation that will never change, and</li>
<li>it does not quite handle overlapping objects correctly.</li>
</ol>
<p>What I mean by the second one is basically given this structure:</p>
<blockquote>
<div class="sourceCode" id="cb3"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb3-1"><a href="#cb3-1"></a><span class="kw">struct</span> Empty <span class="op">{</span> <span class="op">}</span>;</span>
<span id="cb3-2"><a href="#cb3-2"></a></span>
<span id="cb3-3"><a href="#cb3-3"></a><span class="kw">struct</span> Sub <span class="op">:</span> Empty <span class="op">{</span></span>
<span id="cb3-4"><a href="#cb3-4"></a>    BufferStorage<span class="op">&lt;</span>Empty<span class="op">&gt;</span> buffer_storage;</span>
<span id="cb3-5"><a href="#cb3-5"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
<p>If we initialize the <code class="sourceCode cpp">Empty</code> that <code class="sourceCode cpp">buffer_storage</code> is intended to have, then <code class="sourceCode cpp">Sub</code> has two subobjects of type <code class="sourceCode cpp">Empty</code>. But the compiler doesn’t really… know that, and doesn’t adjust them accordingly. As a result, the <code class="sourceCode cpp">Empty</code> base class subobject and the <code class="sourceCode cpp">Empty</code> initialized in <code class="sourceCode cpp">buffer_storage</code> are at the same address, which violates the rule that all objects of one type are at unique addresses.</p>
<p>An alternative approach to storage is to use a <code class="sourceCode cpp"><span class="kw">union</span></code>:</p>
<blockquote>
<div class="sourceCode" id="cb4"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb4-1"><a href="#cb4-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T<span class="op">&gt;</span></span>
<span id="cb4-2"><a href="#cb4-2"></a><span class="kw">struct</span> UnionStorage <span class="op">{</span></span>
<span id="cb4-3"><a href="#cb4-3"></a><span class="kw">private</span><span class="op">:</span></span>
<span id="cb4-4"><a href="#cb4-4"></a>  <span class="kw">union</span> <span class="op">{</span> T value; <span class="op">}</span>;</span>
<span id="cb4-5"><a href="#cb4-5"></a></span>
<span id="cb4-6"><a href="#cb4-6"></a><span class="kw">public</span><span class="op">:</span></span>
<span id="cb4-7"><a href="#cb4-7"></a>  <span class="co">// accessors</span></span>
<span id="cb4-8"><a href="#cb4-8"></a><span class="op">}</span>;</span>
<span id="cb4-9"><a href="#cb4-9"></a></span>
<span id="cb4-10"><a href="#cb4-10"></a><span class="kw">struct</span> Sub <span class="op">:</span> Empty <span class="op">{</span></span>
<span id="cb4-11"><a href="#cb4-11"></a>    UnionStorage<span class="op">&lt;</span>Empty<span class="op">&gt;</span> union_storage;</span>
<span id="cb4-12"><a href="#cb4-12"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
<p>Here, now the compiler knows for sure there is an <code class="sourceCode cpp">Empty</code> in <code class="sourceCode cpp">union_storage</code> and will lay out the types appropriately. See also <a href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112591">gcc bug 112591</a>.</p>
<p>So it seems that the <code class="sourceCode cpp">UnionStorage</code> approach is strictly superior: it will work in constexpr and it lays out overlapping types properly. But it has limitations of its own. As with the <code class="sourceCode cpp">FixedVector</code> example earlier, you cannot just start the lifetime of <code class="sourceCode cpp">value</code>. But also in this case we run into the <code class="sourceCode cpp"><span class="kw">union</span></code> rules for special member functions: a special member of a <code class="sourceCode cpp"><span class="kw">union</span></code>, by default, is either trivial (if that special member for all alternatives is trivial) or deleted (otherwise). Which means that <code class="sourceCode cpp">UnionStorage<span class="op">&lt;</span>std<span class="op">::</span>string<span class="op">&gt;</span></code> has both its constructor and destructor <em>deleted</em>.</p>
<p>We can work around this by simply adding an empty constructor and destructor (as shown earlier as well):</p>
<blockquote>
<div class="sourceCode" id="cb5"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb5-1"><a href="#cb5-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T<span class="op">&gt;</span></span>
<span id="cb5-2"><a href="#cb5-2"></a><span class="kw">struct</span> UnionStorage2 <span class="op">{</span></span>
<span id="cb5-3"><a href="#cb5-3"></a><span class="kw">private</span><span class="op">:</span></span>
<span id="cb5-4"><a href="#cb5-4"></a>  <span class="kw">union</span> U <span class="op">{</span> U<span class="op">()</span> <span class="op">{</span> <span class="op">}</span> <span class="op">~</span>U<span class="op">()</span> <span class="op">{</span> <span class="op">}</span> T value; <span class="op">}</span>;</span>
<span id="cb5-5"><a href="#cb5-5"></a>  U u;</span>
<span id="cb5-6"><a href="#cb5-6"></a></span>
<span id="cb5-7"><a href="#cb5-7"></a><span class="kw">public</span><span class="op">:</span></span>
<span id="cb5-8"><a href="#cb5-8"></a>  <span class="co">// accessors</span></span>
<span id="cb5-9"><a href="#cb5-9"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
<p>This is a fundamentally weird concept since <code class="sourceCode cpp">U</code> there has a destructor that does nothing (and given that this is a class to be used for uninitialized storage), it <em>should</em> do nothing - that’s correct. But that destructor still isn’t trivial. And it turns out there is still a difference between “destructor that does nothing” and “trivial destructor”:</p>
<table>
<thead>
<tr class="header">
<th><div style="text-align:center">
<strong>Trivially Destructible</strong>
</div></th>
<th><div style="text-align:center">
<strong>Non-trivially Destructible</strong>
</div></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><div class="sourceCode" id="cb6"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb6-1"><a href="#cb6-1"></a><span class="kw">struct</span> A <span class="op">{</span> <span class="op">}</span>;</span>
<span id="cb6-2"><a href="#cb6-2"></a></span>
<span id="cb6-3"><a href="#cb6-3"></a><span class="kw">auto</span> alloc_a<span class="op">(</span><span class="dt">int</span> n<span class="op">)</span> <span class="op">-&gt;</span> A<span class="op">*</span> <span class="op">{</span> <span class="cf">return</span> <span class="kw">new</span> A<span class="op">[</span>n<span class="op">]</span>; <span class="op">}</span></span>
<span id="cb6-4"><a href="#cb6-4"></a><span class="kw">auto</span> del<span class="op">(</span>A<span class="op">*</span> p<span class="op">)</span> <span class="op">-&gt;</span> <span class="dt">void</span> <span class="op">{</span> <span class="kw">delete</span> <span class="op">[]</span> p; <span class="op">}</span></span></code></pre></div></td>
<td><div class="sourceCode" id="cb7"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb7-1"><a href="#cb7-1"></a><span class="kw">struct</span> B <span class="op">{</span> <span class="op">~</span>B<span class="op">()</span> <span class="op">{</span> <span class="op">}</span> <span class="op">}</span>;</span>
<span id="cb7-2"><a href="#cb7-2"></a></span>
<span id="cb7-3"><a href="#cb7-3"></a><span class="kw">auto</span> alloc_b<span class="op">(</span><span class="dt">int</span> n<span class="op">)</span> <span class="op">-&gt;</span> B<span class="op">*</span> <span class="op">{</span> <span class="cf">return</span> <span class="kw">new</span> B<span class="op">[</span>n<span class="op">]</span>; <span class="op">}</span></span>
<span id="cb7-4"><a href="#cb7-4"></a><span class="kw">auto</span> del<span class="op">(</span>B<span class="op">*</span> p<span class="op">)</span> <span class="op">-&gt;</span> <span class="dt">void</span> <span class="op">{</span> <span class="kw">delete</span> <span class="op">[]</span> p; <span class="op">}</span></span></code></pre></div></td>
</tr>
<tr class="even">
<td><div class="sourceCode" id="cb1"><pre class="sourceCode asm"><code class="sourceCode fasm"><span id="cb1-1"><a href="#cb1-1"></a>alloc_a(<span class="bu">int</span>):</span>
<span id="cb1-2"><a href="#cb1-2"></a>        <span class="bu">movsx</span>   <span class="kw">rdi</span>, <span class="kw">edi</span></span>
<span id="cb1-3"><a href="#cb1-3"></a>        <span class="bu">jmp</span>     operator new[](unsigned long)</span>
<span id="cb1-4"><a href="#cb1-4"></a></span>
<span id="cb1-5"><a href="#cb1-5"></a>del(A*):</span>
<span id="cb1-6"><a href="#cb1-6"></a>        <span class="bu">test</span>    <span class="kw">rdi</span>, <span class="kw">rdi</span></span>
<span id="cb1-7"><a href="#cb1-7"></a>        <span class="bu">je</span>      .L3</span>
<span id="cb1-8"><a href="#cb1-8"></a>        <span class="bu">jmp</span>     operator delete[](void*)</span>
<span id="cb1-9"><a href="#cb1-9"></a><span class="fu">.L3:</span></span>
<span id="cb1-10"><a href="#cb1-10"></a>        <span class="bu">ret</span></span></code></pre></div></td>
<td><div class="sourceCode" id="cb2"><pre class="sourceCode asm"><code class="sourceCode fasm"><span id="cb2-1"><a href="#cb2-1"></a>alloc_b(<span class="bu">int</span>):</span>
<span id="cb2-2"><a href="#cb2-2"></a>        movabs  <span class="kw">rax</span>, <span class="dv">9223372036854775800</span></span>
<span id="cb2-3"><a href="#cb2-3"></a>        <span class="bu">push</span>    <span class="kw">rbx</span></span>
<span id="cb2-4"><a href="#cb2-4"></a>        <span class="bu">movsx</span>   <span class="kw">rbx</span>, <span class="kw">edi</span></span>
<span id="cb2-5"><a href="#cb2-5"></a>        <span class="bu">cmp</span>     <span class="kw">rax</span>, <span class="kw">rbx</span></span>
<span id="cb2-6"><a href="#cb2-6"></a>        <span class="bu">lea</span>     <span class="kw">rdi</span>, [<span class="kw">rbx</span>+<span class="dv">8</span>]</span>
<span id="cb2-7"><a href="#cb2-7"></a>        <span class="bu">mov</span>     <span class="kw">rax</span>, <span class="dv">-1</span></span>
<span id="cb2-8"><a href="#cb2-8"></a>        <span class="bu">cmovb</span>   <span class="kw">rdi</span>, <span class="kw">rax</span></span>
<span id="cb2-9"><a href="#cb2-9"></a>        <span class="bu">call</span>    operator new[](unsigned long)</span>
<span id="cb2-10"><a href="#cb2-10"></a>        <span class="bu">mov</span>     <span class="dt">QWORD</span> <span class="dt">PTR</span> [<span class="kw">rax</span>], <span class="kw">rbx</span></span>
<span id="cb2-11"><a href="#cb2-11"></a>        <span class="bu">add</span>     <span class="kw">rax</span>, <span class="dv">8</span></span>
<span id="cb2-12"><a href="#cb2-12"></a>        <span class="bu">pop</span>     <span class="kw">rbx</span></span>
<span id="cb2-13"><a href="#cb2-13"></a>        <span class="bu">ret</span></span>
<span id="cb2-14"><a href="#cb2-14"></a></span>
<span id="cb2-15"><a href="#cb2-15"></a>del(B*):</span>
<span id="cb2-16"><a href="#cb2-16"></a>        <span class="bu">test</span>    <span class="kw">rdi</span>, <span class="kw">rdi</span></span>
<span id="cb2-17"><a href="#cb2-17"></a>        <span class="bu">je</span>      .L9</span>
<span id="cb2-18"><a href="#cb2-18"></a>        <span class="bu">mov</span>     <span class="kw">rax</span>, <span class="dt">QWORD</span> <span class="dt">PTR</span> [<span class="kw">rdi</span><span class="dv">-8</span>]</span>
<span id="cb2-19"><a href="#cb2-19"></a>        <span class="bu">sub</span>     <span class="kw">rdi</span>, <span class="dv">8</span></span>
<span id="cb2-20"><a href="#cb2-20"></a>        <span class="bu">lea</span>     <span class="kw">rsi</span>, [<span class="kw">rax</span>+<span class="dv">8</span>]</span>
<span id="cb2-21"><a href="#cb2-21"></a>        <span class="bu">jmp</span>     operator delete[](void*, unsigned long)</span>
<span id="cb2-22"><a href="#cb2-22"></a><span class="fu">.L9:</span></span>
<span id="cb2-23"><a href="#cb2-23"></a>        <span class="bu">ret</span></span></code></pre></div></td>
</tr>
</tbody>
</table>
<p>That’s a big difference in code-gen, due to the need to put a cookie in the allocation so that the corresponding <code class="sourceCode cpp"><span class="kw">delete</span><span class="op">[]</span></code> knows how many elements there so that their destructors (even though they do nothing!) can be invoked.</p>
<p>While the union storage solution solves some language problems for us, the buffer storage solution can lead to more efficient code - because <code class="sourceCode cpp">StorageBuffer<span class="op">&lt;</span>T<span class="op">&gt;</span></code> is always trivially trivially destructible. It would be nice if he had a good solution to all of these problems - and that solution was also the most efficient one.</p>
<h1 data-number="3" style="border-bottom:1px solid #cccccc" id="design-space"><span class="header-section-number">3</span> Design Space<a href="#design-space" class="self-link"></a></h1>
<p>A previous revision of this paper <span class="citation" data-cites="P3074R0">[<a href="#ref-P3074R0" role="doc-biblioref">P3074R0</a>]</span> talked about three potential solutions to this problem:</p>
<ol type="1">
<li>a library solution (add a <code class="sourceCode cpp">std<span class="op">::</span>uninitialized<span class="op">&lt;</span>T<span class="op">&gt;</span></code>)</li>
<li>just make it work (change the union rules to implicitly start the lifetime of the first alternative, if it’s an implicit-lifetime type)</li>
<li>add a library function to explicitly start lifetime</li>
</ol>
<p>That paper proposed a new function <code class="sourceCode cpp">std<span class="op">::</span>start_lifetime<span class="op">(</span>p<span class="op">)</span></code> that was that third option. However, with the addition of the overlapping subobjects problem and the realization that the union solution has overhead compared to the buffer storage solution, it would be more desirable to solve both problems in one go.</p>
<p>Now, (2) is no longer a meaningful option because we can’t really “just make it work” since attempting to change the union rules with regards to trivial destruction would be quite a language change and an ABI break.</p>
<p>Similarly, (3) doesn’t really address the storage problem. In order to make the <code class="sourceCode cpp"><span class="kw">union</span></code> solution work out, we’d need to add another way to tell the compiler that we want our constructor and destructor to be trivial - not deleted - regardless of the alternatives. Perhaps that ends up being something like this:</p>
<blockquote>
<div class="sourceCode" id="cb8"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb8-1"><a href="#cb8-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T<span class="op">&gt;</span></span>
<span id="cb8-2"><a href="#cb8-2"></a><span class="kw">struct</span> UnionStorageFuture <span class="op">{</span></span>
<span id="cb8-3"><a href="#cb8-3"></a>    <span class="kw">union</span> <span class="op">{</span> <span class="op">[[</span><span class="at">uninitialized</span><span class="op">]]</span> T value; <span class="op">}</span>;</span>
<span id="cb8-4"><a href="#cb8-4"></a>    <span class="kw">constexpr</span> UnionStorageFuture<span class="op">()</span> <span class="op">{</span> std<span class="op">::</span>start_lifetime<span class="op">(&amp;</span>value<span class="op">)</span>; <span class="op">}</span></span>
<span id="cb8-5"><a href="#cb8-5"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
<p>However, now we need two features - some way to mark the alternative and some way to start its lifetime. That, inherently, doesn’t seem like a great solution.</p>
<p>Which seems to leave only one solution to the problem, which is easier to use anyway:</p>
<h2 data-number="3.1" id="a-library-type-stduninitializedt"><span class="header-section-number">3.1</span> A library type: <code class="sourceCode cpp">std<span class="op">::</span>uninitialized<span class="op">&lt;</span>T<span class="op">&gt;</span></code><a href="#a-library-type-stduninitializedt" class="self-link"></a></h2>
<p>We could introduce another magic library type, <code class="sourceCode cpp">std<span class="op">::</span>uninitialized<span class="op">&lt;</span>T<span class="op">&gt;</span></code>, with an interface like:</p>
<blockquote>
<div class="sourceCode" id="cb9"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb9-1"><a href="#cb9-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb9-2"><a href="#cb9-2"></a><span class="kw">struct</span> uninitialized <span class="op">{</span></span>
<span id="cb9-3"><a href="#cb9-3"></a>    <span class="kw">union</span> <span class="op">{</span> T value; <span class="op">}</span>;</span>
<span id="cb9-4"><a href="#cb9-4"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
<p>As basically a better version of <code class="sourceCode cpp">std<span class="op">::</span>aligned_storage</code>. Here is storage for a <code class="sourceCode cpp">T</code>, that implicitly begins its lifetime if <code class="sourceCode cpp">T</code> is an implicit-lifetime-type, but otherwise will not actually initialize it for you - you have to do that yourself. Likewise it will not destroy it for you, you have to do that yourself too. This type would be specified to always be trivially default constructible and trivially destructible. It would be trivially copyable if <code class="sourceCode cpp">T</code> is trivially copyable, otherwise not copyable.</p>
<p><code class="sourceCode cpp">std<span class="op">::</span>inplace_vector<span class="op">&lt;</span>T, N<span class="op">&gt;</span></code> would then have a <code class="sourceCode cpp">std<span class="op">::</span>uninitialized<span class="op">&lt;</span>T<span class="op">[</span>N<span class="op">]&gt;</span></code> and go ahead and <code class="sourceCode cpp">std<span class="op">::</span>construct_at</code> (or, with <span class="citation" data-cites="P2747R1">[<a href="#ref-P2747R1" role="doc-biblioref">P2747R1</a>]</span>, simply placement-new) into the appropriate elements of that array and everything would just work.</p>
<p>Because the language would recognize this type, this would also solve the overlapping objects problem.</p>
<h2 data-number="3.2" id="a-language-annotation"><span class="header-section-number">3.2</span> A language annotation<a href="#a-language-annotation" class="self-link"></a></h2>
<p>During the EWG telecon in <a href="https://wiki.edg.com/bin/view/Wg21telecons2024/P3074R1-EWG">January 2023</a>, the suggestion was made that instead of a magic library type like <code class="sourceCode cpp">std<span class="op">::</span>uninitialized<span class="op">&lt;</span>T<span class="op">&gt;</span></code>, we could instead have some kind of language annotation to achieve the same effect.</p>
<p>For example:</p>
<blockquote>
<div class="sourceCode" id="cb10"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb10-1"><a href="#cb10-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T, <span class="dt">size_t</span> N<span class="op">&gt;</span></span>
<span id="cb10-2"><a href="#cb10-2"></a><span class="kw">struct</span> FixedVector <span class="op">{</span></span>
<span id="cb10-3"><a href="#cb10-3"></a>    <span class="co">// as a library feature</span></span>
<span id="cb10-4"><a href="#cb10-4"></a>    std<span class="op">::</span>uninitialized<span class="op">&lt;</span>T<span class="op">[</span>N<span class="op">]&gt;</span> lib;</span>
<span id="cb10-5"><a href="#cb10-5"></a></span>
<span id="cb10-6"><a href="#cb10-6"></a>    <span class="co">//as a language feature, something like this</span></span>
<span id="cb10-7"><a href="#cb10-7"></a>    <span class="cf">for</span> storage T lang<span class="op">[</span>N<span class="op">]</span>;</span>
<span id="cb10-8"><a href="#cb10-8"></a>    T storage<span class="op">[</span>N<span class="op">]</span> <span class="op">=</span> <span class="cf">for</span> lang;</span>
<span id="cb10-9"><a href="#cb10-9"></a>    uninitialized T lang<span class="op">[</span>N<span class="op">]</span>;</span>
<span id="cb10-10"><a href="#cb10-10"></a></span>
<span id="cb10-11"><a href="#cb10-11"></a>    <span class="dt">size_t</span> size <span class="op">=</span> <span class="dv">0</span>;</span>
<span id="cb10-12"><a href="#cb10-12"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
<p>The advantage of the language syntax is that you can directly use <code class="sourceCode cpp">lang</code> - you would placement new onto <code class="sourceCode cpp">lang<span class="op">[</span><span class="dv">0</span><span class="op">]</span></code>, you read from <code class="sourceCode cpp">lang<span class="op">[</span><span class="dv">1</span><span class="op">]</span></code>, etc, whereas with the library syntax you have to placement new onto <code class="sourceCode cpp">lib<span class="op">.</span>value<span class="op">[</span><span class="dv">0</span><span class="op">]</span></code> and read from <code class="sourceCode cpp">lib<span class="op">.</span>value<span class="op">[</span><span class="dv">1</span><span class="op">]</span></code>, etc.</p>
<p>However, an uninitialized object of type <code class="sourceCode cpp">T</code> really isn’t the same thing as a <code class="sourceCode cpp">T</code>. <code class="sourceCode cpp"><span class="kw">decltype</span><span class="op">(</span>lang<span class="op">)</span></code> would have to be <code class="sourceCode cpp">T</code>, any kind of (imminent) reflection over this type would give you a <code class="sourceCode cpp">T</code>. But there might not actually be a <code class="sourceCode cpp">T</code> there yet, it behaves like a <code class="sourceCode cpp"><span class="kw">union</span> <span class="op">{</span> T; <span class="op">}</span></code> rather than a <code class="sourceCode cpp">T</code>, so spelling it <code class="sourceCode cpp">T</code> strikes me as misleading.</p>
<p>We would have to ensure that all the other member-wise algorithms we have today (the special member functions and the comparisons) use the “uninitialized <code class="sourceCode cpp">T</code>” meaning rather than the <code class="sourceCode cpp">T</code> meaning. And with reflection, that also means all future member-wise algorithms would have to account for this also - rather than rejecting <code class="sourceCode cpp"><span class="kw">union</span></code>s.</p>
<p>The syntactic benefits of the language syntax are nice, but this is a rarely used type for specific situations - so having slightly longer syntax (and really, <code class="sourceCode cpp">lib<span class="op">.</span>value</code> is not especially cumbersome) is not only not a big downside here but could even be viewed as a benefit.</p>
<p>So despite the fact that there was consensus to prefer a language solution over a library solution:</p>
<table>
<thead>
<tr class="header">
<th><div style="text-align:center">
<strong>SF</strong>
</div></th>
<th><div style="text-align:center">
<strong>F</strong>
</div></th>
<th><div style="text-align:center">
<strong>N</strong>
</div></th>
<th><div style="text-align:center">
<strong>A</strong>
</div></th>
<th><div style="text-align:center">
<strong>SA</strong>
</div></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>5</td>
<td>4</td>
<td>4</td>
<td>2</td>
<td>1</td>
</tr>
</tbody>
</table>
<p>Having had more time to consider it, I believe the library solution to be superior.</p>
<h2 data-number="3.3" id="existing-practice"><span class="header-section-number">3.3</span> Existing Practice<a href="#existing-practice" class="self-link"></a></h2>
<p>There are two similar features in other languages that I’m aware of.</p>
<p>Rust has <a href="https://doc.rust-lang.org/std/mem/union.MaybeUninit.html"><code class="sourceCode cpp">MaybeUninit<span class="op">&lt;</span>T<span class="op">&gt;</span></code></a> which is similar to what’s proposed here as <code class="sourceCode cpp">std<span class="op">::</span>uninitialized<span class="op">&lt;</span>T<span class="op">&gt;</span></code>.</p>
<p>Kotlin has a <a href="https://kotlinlang.org/docs/properties.html#late-initialized-properties-and-variables"><code class="sourceCode cpp">lateinit var</code></a> language feature, which is similar to some kind of language annotation (although additionally allows for checking whether it has been initialized, which the language feature would not provide).</p>
<h1 data-number="4" style="border-bottom:1px solid #cccccc" id="wording"><span class="header-section-number">4</span> Wording<a href="#wording" class="self-link"></a></h1>
<p>Add to <span>20.2.2 <a href="https://wg21.link/memory.syn">[memory.syn]</a></span>:</p>
<blockquote>
<div>
<div class="sourceCode" id="cb11"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb11-1"><a href="#cb11-1"></a>namespace std {</span>
<span id="cb11-2"><a href="#cb11-2"></a>  // ...</span>
<span id="cb11-3"><a href="#cb11-3"></a>  // [obj.lifetime], explicit lifetime management</span>
<span id="cb11-4"><a href="#cb11-4"></a>  template&lt;class T&gt;</span>
<span id="cb11-5"><a href="#cb11-5"></a>    T* start_lifetime_as(void* p) noexcept;                                         // freestanding</span>
<span id="cb11-6"><a href="#cb11-6"></a>  template&lt;class T&gt;</span>
<span id="cb11-7"><a href="#cb11-7"></a>    const T* start_lifetime_as(const void* p) noexcept;                             // freestanding</span>
<span id="cb11-8"><a href="#cb11-8"></a>  template&lt;class T&gt;</span>
<span id="cb11-9"><a href="#cb11-9"></a>    volatile T* start_lifetime_as(volatile void* p) noexcept;                       // freestanding</span>
<span id="cb11-10"><a href="#cb11-10"></a>  template&lt;class T&gt;</span>
<span id="cb11-11"><a href="#cb11-11"></a>    const volatile T* start_lifetime_as(const volatile void* p) noexcept;           // freestanding</span>
<span id="cb11-12"><a href="#cb11-12"></a>  template&lt;class T&gt;</span>
<span id="cb11-13"><a href="#cb11-13"></a>    T* start_lifetime_as_array(void* p, size_t n) noexcept;                         // freestanding</span>
<span id="cb11-14"><a href="#cb11-14"></a>  template&lt;class T&gt;</span>
<span id="cb11-15"><a href="#cb11-15"></a>    const T* start_lifetime_as_array(const void* p, size_t n) noexcept;             // freestanding</span>
<span id="cb11-16"><a href="#cb11-16"></a>  template&lt;class T&gt;</span>
<span id="cb11-17"><a href="#cb11-17"></a>    volatile T* start_lifetime_as_array(volatile void* p, size_t n) noexcept;       // freestanding</span>
<span id="cb11-18"><a href="#cb11-18"></a>  template&lt;class T&gt;</span>
<span id="cb11-19"><a href="#cb11-19"></a>    const volatile T* start_lifetime_as_array(const volatile void* p,               // freestanding</span>
<span id="cb11-20"><a href="#cb11-20"></a>                                          size_t n) noexcept;</span>
<span id="cb11-21"><a href="#cb11-21"></a></span>
<span id="cb11-22"><a href="#cb11-22"></a><span class="va">+ template&lt;class T&gt;</span></span>
<span id="cb11-23"><a href="#cb11-23"></a><span class="va">+   union uninitialized;                                                           // freestanding</span></span>
<span id="cb11-24"><a href="#cb11-24"></a>}</span></code></pre></div>
</div>
</blockquote>
<p>With corresponding wording in <span>20.2.6 <a href="https://wg21.link/obj.lifetime">[obj.lifetime]</a></span>:</p>
<blockquote>
<div class="addu">
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_1" id="pnum_1">9</a></span> The union <code class="sourceCode cpp">uninitialized</code> is suitable for storage for an object of type <code class="sourceCode cpp">T</code> that is not initially initialized.</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb12-1"><a href="#cb12-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> T<span class="op">&gt;</span></span>
<span id="cb12-2"><a href="#cb12-2"></a><span class="kw">union</span> uninitialized <span class="op">{</span></span>
<span id="cb12-3"><a href="#cb12-3"></a>  T value;</span>
<span id="cb12-4"><a href="#cb12-4"></a></span>
<span id="cb12-5"><a href="#cb12-5"></a>  <span class="kw">constexpr</span> uninitialized<span class="op">()</span>;</span>
<span id="cb12-6"><a href="#cb12-6"></a>  <span class="kw">constexpr</span> uninitialized<span class="op">(</span><span class="kw">const</span> uninitialized<span class="op">&amp;)</span>;</span>
<span id="cb12-7"><a href="#cb12-7"></a>  <span class="kw">constexpr</span> uninitialized<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">=(</span><span class="kw">const</span> uninitialized<span class="op">&amp;)</span>;</span>
<span id="cb12-8"><a href="#cb12-8"></a>  <span class="kw">constexpr</span> <span class="op">~</span>uninitialized<span class="op">()</span>;</span>
<span id="cb12-9"><a href="#cb12-9"></a><span class="op">}</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_2" id="pnum_2">10</a></span> <code class="sourceCode cpp">uninitialized<span class="op">&lt;</span>T<span class="op">&gt;</span></code> is a trivially default constructible and trivially destructible type.</p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_3" id="pnum_3">11</a></span> <span class="note"><span>[ <em>Note 1:</em> </span>An object of type <code class="sourceCode cpp">T</code> and the <code class="sourceCode cpp">value</code> subobject of <code class="sourceCode cpp">uninitialized<span class="op">&lt;</span>T<span class="op">&gt;</span></code> have distinct addresses ([intro.object])<span> — <em>end note</em> ]</span></span></p>
<div class="sourceCode" id="cb13"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb13-1"><a href="#cb13-1"></a><span class="kw">constexpr</span> uninitialized<span class="op">()</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_4" id="pnum_4">12</a></span> <em>Effects</em>: If <code class="sourceCode cpp">T</code> is an implicit-lifetime type, begins the lifetime of <code class="sourceCode cpp">value</code>. Otherwise, none. <span class="note"><span>[ <em>Note 2:</em> </span>The constructor of <code class="sourceCode cpp">T</code>, if any, is not called<span> — <em>end note</em> ]</span></span></p>
<div class="sourceCode" id="cb14"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb14-1"><a href="#cb14-1"></a><span class="kw">constexpr</span> uninitialized<span class="op">(</span><span class="kw">const</span> uninitialized<span class="op">&amp;)</span>;</span>
<span id="cb14-2"><a href="#cb14-2"></a><span class="kw">constexpr</span> uninitialized<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">=(</span><span class="kw">const</span> uninitialized<span class="op">&amp;)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_5" id="pnum_5">13</a></span> If <code class="sourceCode cpp">T</code> is a trivially copyable type, then <code class="sourceCode cpp">uninitialized<span class="op">&lt;</span>T<span class="op">&gt;</span></code> is a trivially copyable type. Otherwise, <code class="sourceCode cpp">uninitialized<span class="op">&lt;</span>T<span class="op">&gt;</span></code> is not copyable.</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb15-1"><a href="#cb15-1"></a><span class="kw">constexpr</span> <span class="op">~</span>uninitialized<span class="op">()</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_6" id="pnum_6">14</a></span> <em>Effects</em>: None. <span class="note"><span>[ <em>Note 3:</em> </span>The destructor of <code class="sourceCode cpp">T</code>, if any, is not called<span> — <em>end note</em> ]</span></span></p>
</div>
</blockquote>
<h1 data-number="5" style="border-bottom:1px solid #cccccc" id="bibliography"><span class="header-section-number">5</span> References<a href="#bibliography" class="self-link"></a></h1>
<div id="refs" class="references hanging-indent" role="doc-bibliography">
<div id="ref-P0843R9">
<p>[P0843R9] Gonzalo Brito Gadeschi, Timur Doumler, Nevin Liber, David Sankel. 2023-09-14. inplace_vector. <br />
<a href="https://wg21.link/p0843r9">https://wg21.link/p0843r9</a></p>
</div>
<div id="ref-P2747R0">
<p>[P2747R0] Barry Revzin. 2022-12-17. Limited support for constexpr void*. <br />
<a href="https://wg21.link/p2747r0">https://wg21.link/p2747r0</a></p>
</div>
<div id="ref-P2747R1">
<p>[P2747R1] Barry Revzin. 2023-12-10. constexpr placement new. <br />
<a href="https://wg21.link/p2747r1">https://wg21.link/p2747r1</a></p>
</div>
<div id="ref-P3074R0">
<p>[P3074R0] Barry Revzin. 2023-12-15. constexpr union lifetime. <br />
<a href="https://wg21.link/p3074r0">https://wg21.link/p3074r0</a></p>
</div>
<div id="ref-P3074R1">
<p>[P3074R1] Barry Revzin. 2023. <code class="sourceCode cpp">std<span class="op">::</span>uninitialized<span class="op">&lt;</span>T<span class="op">&gt;</span></code>. <br />
<a href="https://wg21.link/p3074r1">https://wg21.link/p3074r1</a></p>
</div>
</div>
</div>
</div>
</body>
</html>
