<!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="2023-01-24" />
  <title>Deconstructing the Avoidance of Uninitialized Reads of Auto
Variables</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 { } 
code span.al { color: #ff0000; } 
code span.an { } 
code span.at { } 
code span.bn { color: #9f6807; } 
code span.bu { color: #9f6807; } 
code span.cf { color: #00607c; } 
code span.ch { color: #9f6807; } 
code span.cn { } 
code span.co { color: #008000; font-style: italic; } 
code span.cv { color: #008000; font-style: italic; } 
code span.do { color: #008000; } 
code span.dt { color: #00607c; } 
code span.dv { color: #9f6807; } 
code span.er { color: #ff0000; font-weight: bold; } 
code span.ex { } 
code span.fl { color: #9f6807; } 
code span.fu { } 
code span.im { } 
code span.in { color: #008000; } 
code span.kw { color: #00607c; } 
code span.op { color: #af1915; } 
code span.ot { } 
code span.pp { color: #6f4e37; } 
code span.re { } 
code span.sc { color: #9f6807; } 
code span.ss { color: #9f6807; } 
code span.st { color: #9f6807; } 
code span.va { } 
code span.vs { color: #9f6807; } 
code span.wa { color: #008000; font-weight: bold; } 
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: 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>
  <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">Deconstructing the Avoidance
of Uninitialized Reads of Auto Variables</h1>
<table style="border:none;float:right">
  <tr>
    <td>Document #:</td>
    <td>P2754R0</td>
  </tr>
  <tr>
    <td>Date:</td>
    <td>2023-01-24</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>
      isocpp-ext<br>
    </td>
  </tr>
  <tr>
    <td style="vertical-align:top">Reply-to:</td>
    <td>
      Jake Fevold<br>&lt;<a href="mailto:jfevold@bloomberg.net" class="email">jfevold@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="#introduction" id="toc-introduction"><span class="toc-section-number">1</span> Introduction</a></li>
<li><a href="#open-questions-of-scope" id="toc-open-questions-of-scope"><span class="toc-section-number">2</span> Open Questions of Scope</a></li>
<li><a href="#properties-of-a-solution" id="toc-properties-of-a-solution"><span class="toc-section-number">3</span> Properties of a Solution</a></li>
<li><a href="#relevant-code-examples" id="toc-relevant-code-examples"><span class="toc-section-number">4</span> Relevant Code Examples</a>
<ul>
<li><a href="#reading-an-uninitialized-automatic-variable-directly" id="toc-reading-an-uninitialized-automatic-variable-directly"><span class="toc-section-number">4.1</span> Reading an Uninitialized Automatic
Variable Directly</a></li>
<li><a href="#reading-an-uninitialized-automatic-variable-conditionally" id="toc-reading-an-uninitialized-automatic-variable-conditionally"><span class="toc-section-number">4.2</span> Reading an Uninitialized Automatic
Variable Conditionally</a></li>
<li><a href="#passing-an-uninitialized-automatic-variable-to-another-function-by-value" id="toc-passing-an-uninitialized-automatic-variable-to-another-function-by-value"><span class="toc-section-number">4.3</span> Passing an Uninitialized Automatic
Variable to Another Function by Value</a></li>
<li><a href="#passing-a-potentially-uninitialized-automatic-variable-to-another-function-by-value" id="toc-passing-a-potentially-uninitialized-automatic-variable-to-another-function-by-value"><span class="toc-section-number">4.4</span> Passing a Potentially
Uninitialized Automatic Variable to Another Function by Value</a></li>
<li><a href="#passing-an-uninitialized-automatic-variable-to-another-function-by-reference-or-pointer" id="toc-passing-an-uninitialized-automatic-variable-to-another-function-by-reference-or-pointer"><span class="toc-section-number">4.5</span> Passing an Uninitialized Automatic
Variable to Another Function by Reference or Pointer</a></li>
<li><a href="#common-idioms-delaying-initialization-for-performance" id="toc-common-idioms-delaying-initialization-for-performance"><span class="toc-section-number">4.6</span> Common Idioms Delaying
Initialization for Performance</a></li>
<li><a href="#initialization-for-template-types-leaves-room-for-improvement" id="toc-initialization-for-template-types-leaves-room-for-improvement"><span class="toc-section-number">4.7</span> Initialization for Template Types
Leaves Room for Improvement</a></li>
</ul></li>
<li><a href="#suggested-solutions" id="toc-suggested-solutions"><span class="toc-section-number">5</span> Suggested Solutions</a>
<ul>
<li><a href="#always-zero-initialize" id="toc-always-zero-initialize"><span class="toc-section-number">5.1</span> Always Zero-Initialize</a></li>
<li><a href="#zero-initialize-or-diagnose" id="toc-zero-initialize-or-diagnose"><span class="toc-section-number">5.2</span> Zero-Initialize or
Diagnose</a></li>
<li><a href="#force-initialization-in-source" id="toc-force-initialization-in-source"><span class="toc-section-number">5.3</span> Force Initialization in
Source</a></li>
<li><a href="#force-initialization-or-explicit-delayed-initialization-intent-in-source" id="toc-force-initialization-or-explicit-delayed-initialization-intent-in-source"><span class="toc-section-number">5.4</span> Force Initialization or Explicit
Delayed Initialization Intent in Source</a></li>
<li><a href="#initialize-to-implementation-defined-value-but-read-before-write-is-still-undefined-behavior" id="toc-initialize-to-implementation-defined-value-but-read-before-write-is-still-undefined-behavior"><span class="toc-section-number">5.5</span> Initialize to
Implementation-Defined Value, But Read Before Write Is Still Undefined
Behavior</a></li>
<li><a href="#initialize-to-implementation-defined-value-but-read-before-write-is-erroneous-behavior" id="toc-initialize-to-implementation-defined-value-but-read-before-write-is-erroneous-behavior"><span class="toc-section-number">5.6</span> Initialize to
Implementation-Defined Value, But Read Before Write Is
<em>Erroneous</em> <em>Behavior</em></a></li>
<li><a href="#value-initialize-only" id="toc-value-initialize-only"><span class="toc-section-number">5.7</span> Value-Initialize Only</a></li>
</ul></li>
<li><a href="#conclusion" id="toc-conclusion"><span class="toc-section-number">6</span> Conclusion</a></li>
</ul>
</div>
<h1 class="unlisted unnumbered" id="abstract">Abstract<a href="#abstract" class="self-link"></a></h1>
<p>Inadvertently reading uninitialized values of automatic variables on
the program stack presents a common source of security holes. An initial
suggestion was proposed in [P2723R0] as “an opening bid” to get the
discussion started. As a result, a variety of thoughtful proposals have
been offered regarding how the C++ language might be altered to
minimalize or mitigate such occurrences. These suggestions have varying
tradeoffs, especially with respect to safety versus correctness and the
extent to which initial intent is preserved. We attempt to survey the
various alternatives that have been proposed on the The WG21 Reflector
and objectively contrast their respective properties in the hope of
facilitating a productive and fruitful exchange of ideas and opinions at
the February 2023 Standards meeting and in the future.</p>
<h1 data-number="1" id="introduction"><span class="header-section-number">1</span> Introduction<a href="#introduction" class="self-link"></a></h1>
<p>This paper is meant to drive fruitful discussion of the topics
described in JF Bastien’s paper, “Zero-initialize objects of automatic
storage duration” [P2723R0]. The stated goal of Bastien’s paper is to
eliminate, where possible, security problems stemming from an
<em>indeterminate</em> <em>value</em> held by variables of nonclass type
of automatic storage duration. <em>Nonclass</em> types are
<em>arithmetic</em> type, <em>pointer-to-object</em> type,
<em>pointer-to-function</em> type, <em>pointer-to-data-member</em> type,
<em>pointer-to-member-function</em> type, <em>enumeration</em> type,
<code class="sourceCode default">std::nullptr_t</code> (since C++11),
and <em>POD</em> (before C++11), as well as <em>array</em> (of any of
these types).</p>
<p>A similar problem exists with uninitialized dynamic memory (such as
that returned from <code class="sourceCode default">malloc</code>,
<code class="sourceCode default">operator</code>
<code class="sourceCode default">new</code>, and similar allocation
utilities), which is not addressed in Bastien’s paper nor here.</p>
<h1 data-number="2" id="open-questions-of-scope"><span class="header-section-number">2</span> Open Questions of Scope<a href="#open-questions-of-scope" class="self-link"></a></h1>
<p>Considering the various suggested mitigation strategies for security
holes due to typical nonclass variables raised several other questions
regarding scope. That is, should a proposed solution to address scalar
and pointer types also apply to:</p>
<ul>
<li>Dynamic memory returned from
<code class="sourceCode default">malloc</code>,
<code class="sourceCode default">operator new</code>, and similar?</li>
<li>Arrays?</li>
<li>Bytes of a union that are not used by the currently selected
type?</li>
<li>Padding in the object representation?</li>
</ul>
<p>These considerations of scope seem mostly orthogonal to choosing a
basic direction and are not discussed further here.</p>
<h1 data-number="3" id="properties-of-a-solution"><span class="header-section-number">3</span> Properties of a Solution<a href="#properties-of-a-solution" class="self-link"></a></h1>
<p>As part of curating the information provided by proposals and
discussions in The WG21 Reflector, several recurring questions were used
to nail down the salient properties and features of a given proposal. A
well-considered, though non-exhaustive, curation of such questions is
presented here.</p>
<ul>
<li>Does old code that has undefined behavior because of reads of
uninitialized values but is known or believed to work acceptably
continue to compile? If so, under what circumstances (e.g., compiler
flags and so on)?</li>
<li>Does the solution add behaviors that are not well defined today? For
example, does <code class="sourceCode default">int</code>
<code class="sourceCode default">i;</code> go from meaning
“uninitialized” to meaning “initialized to zero”?</li>
<li>Does the solution <em>change</em> the semantics (i.e., observable
behavior) of any existing program?
<ul>
<li>A program that is correct today?</li>
<li>A program that appears to be correct today but isn’t?</li>
</ul></li>
<li>Does quality of implementation play a role in what programs are ill
formed? If one compiler is capable of proving that a value is read
before being initialized, can it fail to compile whereas another
compiler initializes the value and proceeds?</li>
<li>Do tools that are not compiler integrated, like Valgrind, continue
to be usable to detect (i.e., as program defects) semantic reads of
uninitialized variables?</li>
<li>Is reading from a variable without first explicitly initializing or
writing to that variable still incorrect? If not, what default values
are appropriate for pointer-to-member and similar types?</li>
<li>Is an opt-out annotation, per variable, available in the
source?</li>
<li>Is an opt-out tooling annotation (i.e., compiler flag)
included?</li>
<li>Does a given solution allow for evolution to a better solution, such
as a simpler initialization model?</li>
</ul>
<h1 data-number="4" id="relevant-code-examples"><span class="header-section-number">4</span> Relevant Code Examples<a href="#relevant-code-examples" class="self-link"></a></h1>
<p>The examples in this section serve to elucidate various common
security or correctness defects that a viable proposal might
address.</p>
<h2 data-number="4.1" id="reading-an-uninitialized-automatic-variable-directly"><span class="header-section-number">4.1</span> Reading an Uninitialized
Automatic Variable Directly<a href="#reading-an-uninitialized-automatic-variable-directly" class="self-link"></a></h2>
<div class="sourceCode" id="cb1"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a>void f1()</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>{</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>    int p;</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>    int q = p + 1;  // UB</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>The C++ code snippet above is clearly and unconditionally incorrect
today.</p>
<h2 data-number="4.2" id="reading-an-uninitialized-automatic-variable-conditionally"><span class="header-section-number">4.2</span> Reading an Uninitialized
Automatic Variable Conditionally<a href="#reading-an-uninitialized-automatic-variable-conditionally" class="self-link"></a></h2>
<div class="sourceCode" id="cb2"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a>void f2()</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>{</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>    int y;</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>    int z = b ? y + 1 : 0;</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>If <code class="sourceCode default">b</code> is never true, then this
code is technically correct today. If
<code class="sourceCode default">b</code> is never true, then the
conditional serves no purpose.
<code class="sourceCode default">int</code>
<code class="sourceCode default">z</code>
<code class="sourceCode default">=</code>
<code class="sourceCode default">0;</code> is unconditionally an
improvement.</p>
<h2 data-number="4.3" id="passing-an-uninitialized-automatic-variable-to-another-function-by-value"><span class="header-section-number">4.3</span> Passing an Uninitialized
Automatic Variable to Another Function by Value<a href="#passing-an-uninitialized-automatic-variable-to-another-function-by-value" class="self-link"></a></h2>
<div class="sourceCode" id="cb3"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a>void g3(int);</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>void f3()</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>{</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>    int x;</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>    g3(x);  // likely a bug</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>The C++ code snippet above is likely a bug. If the author is certain
<code class="sourceCode default">g3</code> doesn’t use the value of the
argument, then a literal would suffice.</p>
<h2 data-number="4.4" id="passing-a-potentially-uninitialized-automatic-variable-to-another-function-by-value"><span class="header-section-number">4.4</span> Passing a Potentially
Uninitialized Automatic Variable to Another Function by Value<a href="#passing-a-potentially-uninitialized-automatic-variable-to-another-function-by-value" class="self-link"></a></h2>
<div class="sourceCode" id="cb4"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>void g4(int);</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>void f4()</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>{</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>    int s;</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>    if (c) s = 0;</span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>    g4(s);  // likely a bug</span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>If <code class="sourceCode default">g4</code> uses the value of the
parameter only when <code class="sourceCode default">c</code> is true,
then this example code is correct today. Because
<code class="sourceCode default">g4</code> doesn’t take the value of
<code class="sourceCode default">c</code> as a parameter, the example
code likely has a bug.</p>
<h2 data-number="4.5" id="passing-an-uninitialized-automatic-variable-to-another-function-by-reference-or-pointer"><span class="header-section-number">4.5</span> Passing an Uninitialized
Automatic Variable to Another Function by Reference or Pointer<a href="#passing-an-uninitialized-automatic-variable-to-another-function-by-reference-or-pointer" class="self-link"></a></h2>
<div class="sourceCode" id="cb5"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a>void g5(int*);</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>void f5()</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>{</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>    int t;</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>    g5(&amp;t);  // possibly a bug</span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>If <code class="sourceCode default">t</code> is strictly an output of
<code class="sourceCode default">g5</code>, this example code is correct
today. If <code class="sourceCode default">g5</code> compares the
address of <code class="sourceCode default">t</code> but does not
dereference the pointer, this example code is correct today. Compilers
cannot currently reason about the contract of
<code class="sourceCode default">g5</code> when the definition of
<code class="sourceCode default">g5</code> is in a different translation
unit.</p>
<h2 data-number="4.6" id="common-idioms-delaying-initialization-for-performance"><span class="header-section-number">4.6</span> Common Idioms Delaying
Initialization for Performance<a href="#common-idioms-delaying-initialization-for-performance" class="self-link"></a></h2>
<div class="sourceCode" id="cb6"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a>void f6()</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>{</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>    char buffer[1000];</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>    BufferAllocator a(buffer, sizeof buffer);</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>    std::vector v(&amp;a);</span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>    char buffer2[1000];</span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>    snprintf(buffer2, sizeof buffer2, &quot;cstring&quot;);</span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>Idioms like these are safe and efficient and are not a common source
of security concerns.</p>
<h2 data-number="4.7" id="initialization-for-template-types-leaves-room-for-improvement"><span class="header-section-number">4.7</span> Initialization for Template
Types Leaves Room for Improvement<a href="#initialization-for-template-types-leaves-room-for-improvement" class="self-link"></a></h2>
<div class="sourceCode" id="cb7"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a>template &lt;typename T&gt;</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>void f7()</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>{</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>  T t;</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>  cout &lt;&lt; t;</span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>For class types, <code class="sourceCode default">t</code> is
initialized and the C++ code snippet above is correct today. For
primitive types, <code class="sourceCode default">t</code> is
uninitialized and the behavior of
<code class="sourceCode default">f7</code> is undefined.</p>
<h1 data-number="5" id="suggested-solutions"><span class="header-section-number">5</span> Suggested Solutions<a href="#suggested-solutions" class="self-link"></a></h1>
<p>Each solution is evaluated for <em>viability</em>, <em>backward</em>
<em>compatibility</em>, and <em>expressability</em>.</p>
<p><strong>Viability</strong> is an evaluation of whether a solution is
logically consistent, both internally and with respect to the existing
C++ Standard. Viability is summarized for each solution as either
<em>viable</em>, <em>nonviable</em>, or <em>unclear</em>.
<em>Viable</em> means that a given solution is consistent.
<em>Nonviable</em> means that a given solution is inconsistent either
with itself or with other foundational rules or definitions in the
Standard. <em>Unclear</em> means that the available information is
insufficient for making a sound determination.</p>
<p><strong>Backward</strong> <strong>compatibility</strong> is an
evaluation of whether all existing, compiling code would continue to
compile and behave as it does now if a given solution were adopted.
Note, if buggy code continues to compile and behave identically, then
the root security problem is unaddressed. Backward compatibility is
summarized as either <em>compatible</em>, <em>correct-code</em>
<em>compatible</em>, <em>incompatible</em>, or <em>unclear</em>.
<em>Compatible</em> means that, if a given solution were adopted, all
code which previously compiled continues to compile, with behavior
differences only in the case of previously undefined behavior (UB).
<em>Correct-code</em> <em>compatible</em> means that all previous
correct code compiles, but some or all code that had UB would not
compile. <em>Incompatible</em> means that some previously correct code
would not compile. <em>Unclear</em> means that the available information
is insufficient for making a sound determination.</p>
<p><strong>Expressability</strong> is an evaluation of whether
previously existing code would maintain its current meaning if a given
solution were adopted. Currently, an uninitialized automatic nonclass
variable declaration could be either an inadvertent, logical error
(e.g., the original author meant to initialize but didn’t), or an
intentional, delayed initialization. Expressability is summarized as
either <em>better</em>, <em>unchanged</em>, <em>worse</em>, or
<em>unclear</em>. <em>Better</em> means that previously existing code
must be updated to make explicit the intent to delay initialization or
correct the logical error. <em>Unchanged</em> means that previously
existing code would be no more or less ambiguous. <em>Worse</em> means
that previously existing code would be more ambiguous because logical
error and intentionally delayed initialization are no longer the only
two possibilities. <em>Unclear</em> means that the available information
is insufficient for making a sound determination.</p>
<p>Note that some solutions list additional concerns that are not
generally applicable to other solutions.</p>
<h2 data-number="5.1" id="always-zero-initialize"><span class="header-section-number">5.1</span> Always Zero-Initialize<a href="#always-zero-initialize" class="self-link"></a></h2>
<p>All uninitialized automatic-storage-duration nonclass variables are
initialized to a specific value. Numerical types would be initialized to
zero. The value for pointer types is an open question. Major compilers
offer an option to zero-initialize already.</p>
<ul>
<li><p><strong>Viability</strong>: <em>Viable</em>. This solution has
already been implemented and is viable, concrete, and easily
understood.</p></li>
<li><p><strong>Backward</strong> <strong>Compatibility</strong>:
<em>Compatible</em>. All existing code continues to compile, and all
existing correct code continues to work correctly. Behavior of some
existing code that was previously undefined becomes defined, though that
now-defined behavior might not be correct. Importantly, incorrect code
that was previously working properly might now exhibit different,
unexpected behavior, which could be better or worse.</p></li>
<li><p><strong>Expressability</strong>: <em>Worse</em>. Currently, a
declaration without an initialization is either an accidental omission
or an intentional delayed initialization, meaning a promise to write
before read. Going forward, a declaration without an initialization will
be indistinguishable between an unintentional failure to initialize and
an intentional zero initialization. All the examples listed become well
defined in all branches. For existing bugs, the new well-defined
behavior might, by happenstance, be the intended behavior, or it might
not.</p></li>
<li><p><em>Other Concerns</em>: Tooling. No tools will be able to detect
existing logical errors since they will become indistinguishable from
intentional zero initialization. The declarations
<code class="sourceCode default">int</code>
<code class="sourceCode default">i;</code> and
<code class="sourceCode default">int</code>
<code class="sourceCode default">i</code>
<code class="sourceCode default">=</code>
<code class="sourceCode default">0;</code> would have precisely the same
meaning.</p></li>
</ul>
<h2 data-number="5.2" id="zero-initialize-or-diagnose"><span class="header-section-number">5.2</span> Zero-Initialize or Diagnose<a href="#zero-initialize-or-diagnose" class="self-link"></a></h2>
<p>Code having an unconditional read of an indeterminate value is
diagnosed (i.e., rejected), and code with a potential read of an
indeterminate value must zero-initialize the variable and accept the
code as well formed.</p>
<ul>
<li><p><strong>Viability</strong>: <em>Unclear</em>. Whether this
solution is viable depends on the verbiage with respect to the abstract
machine, for which no proposal is currently available. Rejecting code in
which indeterminate value is unconditionally read relies on the quality
of the implementation. Stating both that the value of an uninitialized
variable is zero <em>and</em> that the behavior of reading that value is
undefined is inconsistent. Also problematic is stating that the result
of reading an uninitialized variable is, depending on the
implementation, either (1) well defined (as having a value of zero) or
(2) disallowed.</p></li>
<li><p><strong>Backward</strong> <strong>Compatibility</strong>:
<em>Correct-Code</em> <em>Compatible</em>. Some number of existing bugs
that would previously compile will now fail to compile, specifically
some but not necessarily all bugs where a read of indeterminate value is
unconditional. All bugs conditional on runtime values will continue to
compile, and will have deterministic outcomes, which might not be
correct and might even cause a program that appears to be working to
suddenly exhibit different, unexpected behavior.</p></li>
<li><p><strong>Expressability</strong>: <em>Unchanged</em>. By allowing
a diagnostic, the semantics of uninitialized variables remain
unchanged.</p></li>
<li><p><em>Other</em> <em>Concerns</em>: Validity becomes dependent on
quality of implementation. This solution would introduce a condition
where code that is accepted by one conformant compiler might not be
accepted by another.</p></li>
</ul>
<h2 data-number="5.3" id="force-initialization-in-source"><span class="header-section-number">5.3</span> Force Initialization in
Source<a href="#force-initialization-in-source" class="self-link"></a></h2>
<p>All uninitialized automatic-storage-duration nonclass variables are
ill formed. Delayed initialization would require use of
<code class="sourceCode default">std::optional</code> or a similar
mechanism.</p>
<ul>
<li><p><strong>Viability</strong>: <em>Viable</em>. The solution is
viable, concrete, and easily understood.</p></li>
<li><p><strong>Backward</strong> <strong>Compatibility</strong>:
<em>Incompatible</em>. Any existing code having delayed initialization
of automatic-storage-duration nonclass variables would need to be
updated.</p></li>
<li><p><strong>Expressability</strong>: <em>Better</em>. Accidental
omission of an initial value is no longer possible; one must explicitly
choose a class type or provide an initial value. Consequently, a person
must evaluate existing code and make changes. Note that using a script
to initialize every uninitialized automatic variable would be just
another means of masking the original author’s intent.</p></li>
</ul>
<h2 data-number="5.4" id="force-initialization-or-explicit-delayed-initialization-intent-in-source"><span class="header-section-number">5.4</span> Force Initialization or
Explicit Delayed Initialization Intent in Source<a href="#force-initialization-or-explicit-delayed-initialization-intent-in-source" class="self-link"></a></h2>
<p>All uninitialized automatic-storage-duration nonclass variables are
ill formed unless specifically annotated. A suitable syntax must be
chosen to specify when leaving a variable uninitialized is deemed
necessary.</p>
<ul>
<li><p><strong>Viability</strong>: <em>Viable</em>. The solution is
viable, concrete, and easily understood.</p></li>
<li><p><strong>Backward</strong> <strong>Compatibility</strong>:
<em>Incompatible</em>. Any existing code with delayed initialization of
automatic-storage-duration nonclass variables would again need to be
updated. A tool to annotate all such variables as uninitialized could,
however, be easily employed for use cases in which security is not
deemed important.</p></li>
<li><p><strong>Expressability</strong>: <em>Better</em>. Accidental
omission of an initial value is again no longer possible; one must
explicitly choose to annotate or give an initial value. Improvement of
existing code is dependent on the quality of the updates. If all
previously uninitialized variables are mindlessly annotated as
intentionally delayed, then, in practice, correctness bugs become harder
to find.</p></li>
</ul>
<h2 data-number="5.5" id="initialize-to-implementation-defined-value-but-read-before-write-is-still-undefined-behavior"><span class="header-section-number">5.5</span> Initialize to
Implementation-Defined Value, But Read Before Write Is Still Undefined
Behavior<a href="#initialize-to-implementation-defined-value-but-read-before-write-is-still-undefined-behavior" class="self-link"></a></h2>
<p>All uninitialized automatic-storage-duration nonclass variables are
initialized to an implementation-defined value, but reading that value
is still UB. One could, in development and testing, inject values that
are likely to cause noticeable failures (e.g., signaling NaN, unaligned
pointer, and so on) and, in production, inject best-guess values, such
as zero for integers.</p>
<ul>
<li><p><strong>Viability</strong>: <em>Nonviable</em>. Undefined
behavior has a specific meaning; declaring behavior undefined and also
defining some aspects of the behavior is inconsistent with that meaning.
Although we might recommend that all vendors follow this guidance, a
compiler that failed to do so (e.g., to optimize performance) would
nonetheless remain conforming.</p></li>
<li><p><strong>Backward</strong> <strong>Compatibility</strong>:
<em>Compatible</em>. All existing code still compiles, and all existing
correct code works as it did before. Again, compilers that follow this
suggestion might well expose defects in programs that previously were
behaving as expected for all inputs.</p></li>
<li><p><strong>Expressability</strong>: <em>Unchanged</em>. Everything
means exactly what it did before; only the results of previously UB are
allowed (and encouraged) to change.</p></li>
</ul>
<h2 data-number="5.6" id="initialize-to-implementation-defined-value-but-read-before-write-is-erroneous-behavior"><span class="header-section-number">5.6</span> Initialize to
Implementation-Defined Value, But Read Before Write Is
<em>Erroneous</em> <em>Behavior</em><a href="#initialize-to-implementation-defined-value-but-read-before-write-is-erroneous-behavior" class="self-link"></a></h2>
<p>All uninitialized automatic-storage-duration nonclass variables are
initialized to an implementation-defined value, yet reading that value
is always wrong (like <em>UB</em>) but still defined (unlike
<em>UB</em>). The original term proposed for this defined but
undesirable behavior is <em>erroneous</em> <em>behavior</em>
(<em>EB</em>). Any program that contains <em>EB</em> is incorrect, but
the behavior is <em>implementation</em> <em>defined</em>. Different
projects could elect to treat <em>EB</em> as UB for performance, could
use hostile default values for testing and development, or could use
somewhat safe default values for production.</p>
<ul>
<li><p><strong>Viability</strong>: <em>Viable</em>. The solution is
viable because <em>EB</em> is separate from <em>UB</em>, thus avoiding
inconsistency. Getting the wording exactly right might be
challenging.</p></li>
<li><p><strong>Backward</strong> <strong>Compatibility</strong>:
<em>Compatible</em>. Existing, correct programs continue to work exactly
as before. Existing programs with bugs continue to compile, all existing
options for finding bugs continue to be viable, and opportunities for
new tools become available as well. Again, defects in apparently working
programs might manifest as the result of this change, and programs that
had observable defects might suddenly start behaving as
intended.</p></li>
<li><p><strong>Expressability</strong>: <em>Unchanged</em>. Everything
means exactly what it did before.</p></li>
</ul>
<h2 data-number="5.7" id="value-initialize-only"><span class="header-section-number">5.7</span> Value-Initialize Only<a href="#value-initialize-only" class="self-link"></a></h2>
<p>Remove default initialization entirely and have only value
initialization. The state of initialization in C++ is already very
complex, and the cost of this complexity is dubious for the level of
utility it affords. The entire initialization system could be pared down
to one single form of initialization that provides values in all cases.
This more fundamental change addresses uninitialized-variable problems,
as well as other known issues with initialization.</p>
<ul>
<li><p><strong>Viability</strong>: <em>Unclear</em>. While this bold
general reimagining of C++ initialization might be the ideal solution,
many committee members would agree that getting it right would take far
more time than any other solution presented here. Some consider the
security concerns being addressed as distinctly urgent, so waiting for a
broader-scope solution might be considered unacceptable. Arguably, no
solution to the narrow-scope problem should be undertaken if that
narrow-scope solution would substantially restrict future options for a
much improved, wider-scope solution to the complexity-of-initialization
problem.</p></li>
<li><p><strong>Backward</strong> <strong>Compatibility</strong>:
<em>Unclear</em>. Without more information on the specifics, backward
compatibility is difficult to judge.</p></li>
<li><p><strong>Expressability</strong>: <em>Unclear</em>. Without more
information on the specifics, expressability is difficult to
judge.</p></li>
</ul>
<h1 data-number="6" id="conclusion"><span class="header-section-number">6</span> Conclusion<a href="#conclusion" class="self-link"></a></h1>
<p>Inadvertently reading an uninitialized nonclass variable on the
program stack is a known source of difficult to diagnose bugs. Moreover,
these defects lead to security holes that can be additionally
problematic. One possible solution, proposed in [P2723R0], is to simply
zero-initialize every automatic variable. Based on that initial
suggestion, several other solutions have been proposed. We began this
paper by enumerating some related issues involving solution scope
concerning <em>dynamic</em> <em>memory</em>, <em>arrays</em>,
<em>unions</em>, and <em>padding</em>. After identifying several useful
diagnostic questions to elicit important distinguishing properties, we
then proceeded to elucidate the various manifestations of this
correctness and security problem with several small code examples.
Finally, we identified seven different solution approaches and evaluated
them against three separate criteria (<em>viability</em>,
<em>backward</em> <em>compatibility</em>, and <em>expressability</em>),
the results of which are summarized below.</p>
<table>
<thead>
<tr class="header">
<th style="text-align: center;"><div style="text-align:center">
<strong>Section</strong>
</div></th>
<th style="text-align: center;"><div style="text-align:center">
<strong>Proposed Solution</strong>
</div></th>
<th style="text-align: center;"><div style="text-align:center">
<strong>Viability</strong>
</div></th>
<th style="text-align: center;"><div style="text-align:center">
<strong>Backward Compatibility</strong>
</div></th>
<th style="text-align: center;"><div style="text-align:center">
<strong>Expressability</strong>
</div></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: center;">5.1</td>
<td style="text-align: center;">Always Zero-Initialize</td>
<td style="text-align: center;">Viable</td>
<td style="text-align: center;">Compatible</td>
<td style="text-align: center;"><strong>Worse</strong></td>
</tr>
<tr class="even">
<td style="text-align: center;">5.2</td>
<td style="text-align: center;">Zero-Initialize or Diagnose</td>
<td style="text-align: center;"><strong>Unclear</strong></td>
<td style="text-align: center;">Correct-Code Compatible</td>
<td style="text-align: center;">Unchanged</td>
</tr>
<tr class="odd">
<td style="text-align: center;">5.3</td>
<td style="text-align: center;">Force-Initialize in Source</td>
<td style="text-align: center;">Viable</td>
<td style="text-align: center;"><strong>Incompatible</strong></td>
<td style="text-align: center;">Better</td>
</tr>
<tr class="even">
<td style="text-align: center;">5.4</td>
<td style="text-align: center;">Force-Initialize or Annotate</td>
<td style="text-align: center;">Viable</td>
<td style="text-align: center;"><strong>Incompatible</strong></td>
<td style="text-align: center;">Better</td>
</tr>
<tr class="odd">
<td style="text-align: center;">5.5</td>
<td style="text-align: center;">Default Value, Still UB</td>
<td style="text-align: center;"><strong>Nonviable</strong></td>
<td style="text-align: center;">Compatible</td>
<td style="text-align: center;">Unchanged</td>
</tr>
<tr class="even">
<td style="text-align: center;">5.6</td>
<td style="text-align: center;">Default Value, Erroneous</td>
<td style="text-align: center;">Viable</td>
<td style="text-align: center;">Compatible</td>
<td style="text-align: center;">Unchanged</td>
</tr>
<tr class="odd">
<td style="text-align: center;">5.7</td>
<td style="text-align: center;">Value-Initialize Only</td>
<td style="text-align: center;"><strong>Unclear</strong></td>
<td style="text-align: center;"><strong>Unclear</strong></td>
<td style="text-align: center;"><strong>Unclear</strong></td>
</tr>
</tbody>
</table>
<p>Based on this analysis, we conclude that the baseline approach
[section 5.1] of zero-initializing everything, similar to how static
nonclass data is initialized, would be effective at plugging all such
security holes but would add a meaningful definition to currently UB,
which in turn would make diagnosing such inadvertent mistakes more
difficult moving forward.</p>
<p>Combining zero initialization with compile time failure [section 5.2]
has the serious drawback of some compilers accepting code which other
compilers reject. Forced initialization, without [section 5.3] or with
[section 5.4] annotation for intentional delayed initialization, imposes
an enormous effort to modify existing code, even existing correct code.
This change would encourage the cavalier use of scripts to explicitly
default-initialize (or annotate) all previously uninitialized variables,
thereby losing the intent of the original author. This strategy is
likely to be met with resistance by many existing code bases. Requiring
a defined meaning and behavior for UB [section 5.5] is nonviable, and
recommending such behavior, though perfectly reasonable, simply cannot
be enforced on an otherwise compliant implementation.</p>
<p>The <em>EB</em> approach [section 5.6] affords almost all the
advantages of the others with few drawbacks. This strategy will,
however, require some thought to introduce a new kind of behavior, EB,
to the C++ abstract machine. Importantly and unlike many of the other
proposals, defining <em>uninitialized</em> <em>memory</em>
<em>reads</em> as EB provides no hindrance to longer-term solutions,
such as the option of eliminating default initialization entirely
[section 5.7].</p>
</div>
</div>
</body>
</html>
