<!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-10-11" />
  <title>A Safety Profile Verifying Class Initialization</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 { 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 { display: inline-block; 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/vnd.microsoft.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">A Safety Profile Verifying
Class Initialization</h1>
<table style="border:none;float:right">
  <tr>
    <td>Document #:</td>
    <td>P3402R1</td>
  </tr>
  <tr>
    <td>Date:</td>
    <td>2024-10-11</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>
      SG23<br>
    </td>
  </tr>
  <tr>
    <td style="vertical-align:top">Reply-to:</td>
    <td>
      Marc-André Laverdière, Black Duck Software<br>&lt;<a href="mailto:marc-andre.laverdiere@blackduck.com" class="email">marc-andre.laverdiere@blackduck.com</a>&gt;<br>
      Christopher Lapkowski, Black Duck Software<br>&lt;<a href="mailto:redacted@blackduck.com" class="email">redacted@blackduck.com</a>&gt;<br>
      Charles-Henri Gros, Black Duck Software<br>&lt;<a href="mailto:redacted@blackduck.com" class="email">redacted@blackduck.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="#abstract" id="toc-abstract"><span class="toc-section-number">1</span> Abstract</a></li>
<li><a href="#introduction" id="toc-introduction"><span class="toc-section-number">2</span> Introduction</a>
<ul>
<li><a href="#industry-demand" id="toc-industry-demand"><span class="toc-section-number">2.1</span> Industry Demand</a></li>
<li><a href="#profile-guarantees" id="toc-profile-guarantees"><span class="toc-section-number">2.2</span> Profile Guarantees</a></li>
</ul></li>
<li><a href="#definitions" id="toc-definitions"><span class="toc-section-number">3</span> Definitions</a></li>
<li><a href="#exemptions" id="toc-exemptions"><span class="toc-section-number">4</span> Exemptions</a>
<ul>
<li><a href="#exemption-by-type" id="toc-exemption-by-type"><span class="toc-section-number">4.1</span> Exemption by Type</a></li>
<li><a href="#exemption-by-attribute" id="toc-exemption-by-attribute"><span class="toc-section-number">4.2</span> Exemption by Attribute</a></li>
</ul></li>
<li><a href="#constraints-on-static-data-members" id="toc-constraints-on-static-data-members"><span class="toc-section-number">5</span> Constraints on Static Data
Members</a></li>
<li><a href="#verification-of-constructors" id="toc-verification-of-constructors"><span class="toc-section-number">6</span> Verification of
Constructors</a></li>
<li><a href="#templates" id="toc-templates"><span class="toc-section-number">7</span> Templates</a></li>
<li><a href="#idioms-to-consider" id="toc-idioms-to-consider"><span class="toc-section-number">8</span> Idioms to Consider</a>
<ul>
<li><a href="#non-constructor-delegating" id="toc-non-constructor-delegating"><span class="toc-section-number">8.1</span> Non-Constructor
Delegating</a></li>
<li><a href="#discipline-with-const-and-const-parameters" id="toc-discipline-with-const-and-const-parameters"><span class="toc-section-number">8.2</span> Discipline with <code class="sourceCode cpp"><span class="kw">const</span><span class="op">&amp;</span></code>
and <code class="sourceCode cpp"><span class="kw">const</span><span class="op">*</span></code>
Parameters</a></li>
<li><a href="#non-initializing-default-initialization" id="toc-non-initializing-default-initialization"><span class="toc-section-number">8.3</span> Non-Initializing Default
Initialization</a></li>
</ul></li>
<li><a href="#divergences-from-p3274r0" id="toc-divergences-from-p3274r0"><span class="toc-section-number">9</span> Divergences from <span class="citation" data-cites="P3274R0">[P3274R0]</span></a></li>
<li><a href="#future-work" id="toc-future-work"><span class="toc-section-number">10</span> Future Work</a></li>
<li><a href="#conclusion" id="toc-conclusion"><span class="toc-section-number">11</span> Conclusion</a></li>
<li><a href="#straw-polls" id="toc-straw-polls"><span class="toc-section-number">12</span> Straw Polls</a></li>
<li><a href="#bibliography" id="toc-bibliography"><span class="toc-section-number">13</span> References</a></li>
</ul>
</div>
<h1 data-number="1" id="abstract"><span class="header-section-number">1</span> Abstract<a href="#abstract" class="self-link"></a></h1>
<p>We propose an attribute that specifies that every data member that
belongs to a verified class has all its data members initialized to
determinate values, assuming that the data used for construction is
itself initialized properly.</p>
<p>This safety profile restricts what kind of code a constructor can
have. Existing code bases are likely to violate these constraints, and
thus this feature is an opt-in.</p>
<h1 data-number="2" id="introduction"><span class="header-section-number">2</span> Introduction<a href="#introduction" class="self-link"></a></h1>
<p>There is a growing push towards greater memory safety and memory-safe
languages. While C++ is not memory-safe, it is desirable to specify and
opt-in mechanism allowing a subset of C++ features that would result in
memory safe programs. This has been termed ‘profiles’(<span class="citation" data-cites="P3274R0">[<a href="https://wg21.link/p3274r0" role="doc-biblioref">P3274R0</a>]</span>), and would be specified at the
TU level using an attribute. In this paper, we propose <code class="sourceCode cpp"><span class="op">[[</span><span class="at">Profiles</span><span class="op">::</span><span class="at">enable</span><span class="op">(</span><span class="at">initialization</span><span class="op">)]]</span></code>.</p>
<h2 data-number="2.1" id="industry-demand"><span class="header-section-number">2.1</span> Industry Demand<a href="#industry-demand" class="self-link"></a></h2>
<p>Industry compliance standards, such as CERT C++ <span class="citation" data-cites="CertCPP">[<a href="https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=88046682" role="doc-biblioref">CERT</a>]</span>, forbid access of unitialized
memory (Rule EXP53-CPP). While they imply complete initialization, they
do not specify how a good constructor would achieve that objective.</p>
<p>However, the automobile safety industry desires fully initialized
class objects. As part of the The MISRA C++ standard <span class="citation" data-cites="MisraCPP2023">[<a href="https://misra.org.uk/misra-cpp2023-released-including-hardcopy/" role="doc-biblioref">MISRA</a>]</span>, there are two rules that
specifically advise proper initialization of class objects.</p>
<blockquote>
<p>MISRA C++2023 Rule 15.1.2 “All constructors of class should
explicitly initialize all of its virtual base classes and immediate base
classes”</p>
</blockquote>
<blockquote>
<p>MISRA C++2023 Rule 15.1.4 “All direct, non-static data members of a
class should be initialized before the class object is accessable”</p>
</blockquote>
<h2 data-number="2.2" id="profile-guarantees"><span class="header-section-number">2.2</span> Profile Guarantees<a href="#profile-guarantees" class="self-link"></a></h2>
<p>All classes under the purview of the profile attribute will have the
guarantee that all its data members are properly initialized once the
object is constructed, assuming that the data used for construction is
itself initialized properly. In the case of a class that inherits from
one or more classes, all its base classes must be compliant with this
profile.</p>
<p>In this paper, we give examples with the profile attribute attached
to specific classes. We do so to make it clear which classes are
verified classes and which ones aren’t, since some examples have a mix
of them.</p>
<p>Example:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> <span class="op">[[</span><span class="at">Profiles</span><span class="op">::</span><span class="at">enable</span><span class="op">(</span><span class="at">initialization</span><span class="op">)]]</span> parent1 <span class="op">{</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> i;</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>  parent1<span class="op">()</span> <span class="op">=</span> <span class="cf">default</span>; <span class="co">//non-compliant, i is default initialized</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> <span class="op">[[</span><span class="at">Profiles</span><span class="op">::</span><span class="at">enable</span><span class="op">(</span><span class="at">initialization</span><span class="op">)]]</span> child1 <span class="op">:</span> <span class="kw">public</span> parent <span class="op">{</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> j;</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>  child1<span class="op">()</span> <span class="op">:</span> parent1<span class="op">()</span>, j<span class="op">(</span><span class="dv">42</span><span class="op">)</span> <span class="op">{}</span> <span class="co">//child is compliant, but parent isn&#39;t</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a><span class="co">//Not a verified class, but would be compliant if it were</span></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> parent2 <span class="op">{</span></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> i <span class="op">=</span> <span class="dv">0</span>;</span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a>  parent2<span class="op">()</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> <span class="op">[[</span><span class="at">Profiles</span><span class="op">::</span><span class="at">enable</span><span class="op">(</span><span class="at">initialization</span><span class="op">)]]</span> child2 <span class="op">:</span> <span class="kw">public</span> parent2 <span class="op">{</span></span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> j;</span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a>  child<span class="op">()</span> <span class="op">:</span> parent2<span class="op">()</span>, j<span class="op">(</span><span class="dv">42</span><span class="op">)</span> <span class="op">{}</span> <span class="co">//child is not compliant, because parent2 is not a verified class</span></span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<h1 data-number="3" id="definitions"><span class="header-section-number">3</span> Definitions<a href="#definitions" class="self-link"></a></h1>
<p>A <em>verified class</em> is a class that is affected by the profile
attribute or a POD.</p>
<p>An <em>object parameter</em> is either the
<code class="sourceCode cpp"><span class="kw">this</span></code> pointer
or an explicit object parameter ([dcl.fct]).</p>
<p>A <em>verified data member</em> is a data member that is not exempted
from verification.</p>
<p><em>Acceptable inputs</em> are:</p>
<ol type="1">
<li>The non-exempt transitive closure of verified data members</li>
<li>The non-exempt transitive closure of the parameters</li>
<li>Manifestly constant-evaluated expressions ([expr.const])</li>
<li>Object Parameters</li>
<li>Arithmetic operations whose operands are the above</li>
</ol>
<p>The <em>non-exempt transitive closure</em> of X means the set of
symbols that are reachable from X using the dot and arrow operators, and
which are not exempt from verification.</p>
<h1 data-number="4" id="exemptions"><span class="header-section-number">4</span> Exemptions<a href="#exemptions" class="self-link"></a></h1>
<p>Some data members are exempt from verification, either due to
intrinsic properties, or due to explicit opt-out from the developer.</p>
<h2 data-number="4.1" id="exemption-by-type"><span class="header-section-number">4.1</span> Exemption by Type<a href="#exemption-by-type" class="self-link"></a></h2>
<p><span class="citation" data-cites="P3274R0">[<a href="https://wg21.link/p3274r0" role="doc-biblioref">P3274R0</a>]</span> mentions that performance
critical applications won’t initialize output buffers at first and
mentions a few possibilities: “suppression, an uninitialized attribute,
and/or by specific uninitialized types.”</p>
<p>This profile allows a pointer to be initialized to any value, whether
that’s a
<code class="sourceCode cpp"><span class="kw">nullptr</span></code>, the
return value of a
<code class="sourceCode cpp"><span class="kw">new</span></code>, or even
a hardcoded address. It does not require that the memory space pointed
to by the pointer is set to any value. This is an allowance for systems
programming, which sometimes have buffers pointing to hardcoded
addresses, which are used for interacting with devices. We therefore
exempt dynamically allocated memory from initialization in this profile.
Note that this profile prohibits spreading this uninitialized memory to
verified non-static data members through requirement <code class="sourceCode cpp"><span class="op">[</span>only<span class="op">.</span>acceptable<span class="op">.</span>in<span class="op">]</span></code></p>
<p>A cleaner solution for uninitialized memory for the purpose of
buffers, would be to use a specialized type. We envision a class named
<code class="sourceCode cpp">std<span class="op">::</span>RawBuffer<span class="op">&lt;</span>T<span class="op">&gt;</span></code>,
which would record which regions of the buffer have been written
previously, and prohibit reads outside of that region. This class would
have a use beyond this profile, making it a more generic solution.</p>
<p>We leave the general question of pointer safety to <code class="sourceCode cpp"><span class="op">[[</span><span class="at">Profiles</span><span class="op">::</span><span class="at">enable</span><span class="op">(</span><span class="at">Pointers</span><span class="op">)]]</span></code>.</p>
<h2 data-number="4.2" id="exemption-by-attribute"><span class="header-section-number">4.2</span> Exemption by Attribute<a href="#exemption-by-attribute" class="self-link"></a></h2>
<p>Developers could exempt specific data members from verification using
the <code class="sourceCode cpp"><span class="op">[[</span><span class="at">indeterminate</span><span class="op">]]</span></code>
attribute from <span class="citation" data-cites="P2795R5">[<a href="https://wg21.link/p2795r5" role="doc-biblioref">P2795R5</a>]</span>.</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> <span class="op">[[</span><span class="at">Profiles</span><span class="op">::</span><span class="at">enable</span><span class="op">(</span><span class="at">initialization</span><span class="op">)]]</span> HighPerformance <span class="op">{</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>    std<span class="op">::</span>byte<span class="op">*</span> buf <span class="op">[[</span><span class="at">indeterminate</span><span class="op">]]</span>;</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> sz <span class="op">=</span> <span class="op">-</span><span class="dv">1</span>;</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">void</span> fill<span class="op">(</span><span class="co">/*...*/</span><span class="op">)</span>;</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
<h1 data-number="5" id="constraints-on-static-data-members"><span class="header-section-number">5</span> Constraints on Static Data
Members<a href="#constraints-on-static-data-members" class="self-link"></a></h1>
<p>The static data members ([class.static.data]) in a verified class are
allowed in this profile, but, as long they are initialized solely using
constant or zero initialization. This includes
<code class="sourceCode cpp"><span class="kw">constexpr</span></code>
static data members.</p>
<p>Static data members have either static storage duration
([basic.stc.static]) or thread storage duration ([basic.stc.thread]).
They are guaranteed to be initialized with constant initialization
([basic.start.static]). However, they can be reassigned during dynamic
initialization ([basic.start.dynamic]).</p>
<p>Dynamic initialization can lead to subtle bugs, such as:</p>
<ul>
<li>Circular dependencies</li>
<li>Use of statically-initialized values before they are
dynamically-initialized.</li>
<li>Initialization order issues when dealing with symbols variables
defined in other translation units.</li>
<li>Assignment of uninitialized values</li>
</ul>
<p>We illustrate how uninitialized memory can affect static data members
with dynamic initialization below.</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> randomInt<span class="op">()</span> <span class="op">{</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> therandomint;</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> therandomint;</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> <span class="op">[[</span><span class="at">Profiles</span><span class="op">::</span><span class="at">enable</span><span class="op">(</span><span class="at">initialization</span><span class="op">)]]</span> WithStaticUninit1 <span class="op">{</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>    WithStaticUninit1<span class="op">()</span> <span class="op">=</span> <span class="cf">default</span>; <span class="co">//Not a POD</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">static</span> <span class="dt">int</span> thestatic;</span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> WithStaticUninit1<span class="op">::</span>thestatic <span class="op">=</span> randomInt<span class="op">()</span>; <span class="co">//non-compliant</span></span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> <span class="op">[[</span><span class="at">Profiles</span><span class="op">::</span><span class="at">enable</span><span class="op">(</span><span class="at">initialization</span><span class="op">)]]</span> GetsCorrupted <span class="op">{</span></span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a>    GetsCorrupted<span class="op">()</span> <span class="op">:</span> thefield<span class="op">(</span><span class="dv">0</span><span class="op">)</span> <span class="op">{}</span> <span class="co">//compliant</span></span>
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> thefield;</span>
<span id="cb3-15"><a href="#cb3-15" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb3-16"><a href="#cb3-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-17"><a href="#cb3-17" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> <span class="op">[[</span><span class="at">Profiles</span><span class="op">::</span><span class="at">enable</span><span class="op">(</span><span class="at">initialization</span><span class="op">)]]</span> Wrapper <span class="op">{</span></span>
<span id="cb3-18"><a href="#cb3-18" aria-hidden="true" tabindex="-1"></a>    Wrapper<span class="op">()</span> <span class="op">=</span> <span class="cf">default</span>; <span class="co">//Not a POD</span></span>
<span id="cb3-19"><a href="#cb3-19" aria-hidden="true" tabindex="-1"></a>    <span class="kw">static</span> GetsCorrupted wrapped;</span>
<span id="cb3-20"><a href="#cb3-20" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb3-21"><a href="#cb3-21" aria-hidden="true" tabindex="-1"></a>GetsCorrupted corruptingFactory<span class="op">()</span> <span class="op">{</span></span>
<span id="cb3-22"><a href="#cb3-22" aria-hidden="true" tabindex="-1"></a>    GetsCorrupted ret<span class="op">{}</span>;  <span class="co">//All initialized, good</span></span>
<span id="cb3-23"><a href="#cb3-23" aria-hidden="true" tabindex="-1"></a>    ret<span class="op">.</span>thefield <span class="op">=</span> randomInt<span class="op">()</span>; <span class="co">//Now, some uninitialized memory snuck in</span></span>
<span id="cb3-24"><a href="#cb3-24" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> ret;</span>
<span id="cb3-25"><a href="#cb3-25" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb3-26"><a href="#cb3-26" aria-hidden="true" tabindex="-1"></a>GetsCorrupted Wrapper<span class="op">::</span>wrapped <span class="op">=</span> corruptingFactory<span class="op">()</span>; <span class="co">//Non-compliant</span></span></code></pre></div>
<h1 data-number="6" id="verification-of-constructors"><span class="header-section-number">6</span> Verification of Constructors<a href="#verification-of-constructors" class="self-link"></a></h1>
<!--TODO What about updates to static data members? -->
<p>All constructors of a verified class must satisfy the following
properties:</p>
<ul>
<li>[base.are.verified] All base classes must be verified classes.</li>
<li>[base.init.first] All base classes must be initialized before any of
their non-static data members are read.</li>
<li>[delegating.ctor] A delegating constructor is compliant if the
constructor it delegates to is also compliant and it respects the other
rules in this section.</li>
<li>[init.before.read] All verified data members must be initialized
before being read.</li>
<li>[init.all.paths] All verified data members must be initialized on
all paths in the constructor.</li>
<li>[only.acceptable.in] Only acceptable inputs can be assigned to
verified data members and static data members of verified classes.</li>
<li>[no.args] Acceptable inputs cannot be passed by pointer or reference
to function calls, except to constructors.</li>
<li>[effective.const] Except for move constructors, the constructor must
not modify the state of acceptable inputs.</li>
<li>[no.addrof] The address of acceptable inputs cannot be
obtained.</li>
<li>[no.capture] Verified inputs cannot be captured by reference in a
lambda.</li>
</ul>
<p>A data member is considered read whenever it is present in the
function, except when:</p>
<ul>
<li>It is an unevaluated operand ([expr.context])</li>
<li>It is part of a discarded statement ([stmt.if])</li>
<li>It is the left operand of an assignment ([expr.ass])
<!--* It is the receiver object of a constructor invocation--></li>
</ul>
<p>This definition implies the following:</p>
<ul>
<li>The return value of non-manifestly constant-evaluated function calls
may never be assigned to a data member, either directly or
indirectly.</li>
<li>A verified class’ non-static data members are either verified
classes or PODs. Note that PODs don’t have constructors to call, even
though the syntax used may give that impression.</li>
<li>A nonconforming constructor would bring the rejection of its class
only, and not of its subclasses. This decision is intended to reduce the
noisiness that would come from a faulty constructor at the top of a very
large class hierarchy.</li>
<li>An initialized pointer can point to an uninitialized memory region
(e.g. <code class="sourceCode cpp">buf<span class="op">(</span><span class="kw">new</span> <span class="dt">char</span><span class="op">[</span>BUF_SIZE<span class="op">]))</span></code>)
and be compliant. We discuss this <a href="#explicit-exemptions">above</a>.</li>
<li>Default initialization of data members for some types mean that no
initialization is performed ([dcl.init]). Constructors that use this
category of default initialization are non compliant.</li>
<li>Calls to <code class="sourceCode cpp"><span class="kw">operator</span><span class="op">*</span></code>,
<code class="sourceCode cpp"><span class="kw">operator</span><span class="op">-&gt;</span></code>
and <code class="sourceCode cpp"><span class="kw">operator</span><span class="op">-&gt;*</span></code>
are not allowed.</li>
<li>The use of operators
(e.g. <code class="sourceCode cpp"><span class="op">*</span>v</code>,
<code class="sourceCode cpp"><span class="op">&amp;</span>v</code>,
<code class="sourceCode cpp">v<span class="op">[]</span></code>) to
acceptable inputs is not allowed.</li>
<li>The constructor may execute any code that does not affect verified
data members.</li>
<li>Verified data members may never be initialized using an array
subscript.</li>
</ul>
<p>We restrict function calls because we want to keep the analysis
intraprocedural. Initialization that occurs in a member function, or
occurs from a function’s return value, or verifying that arguments are
not tampered with, would require interprocedural analysis. Keeping the
analysis intraprocedural would facilitate adoption.</p>
<p>Examples:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> <span class="op">[[</span><span class="at">Profiles</span><span class="op">::</span><span class="at">enable</span><span class="op">(</span><span class="at">initialization</span><span class="op">)]]</span> clazz1 <span class="op">{</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> i;</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> j;</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> z <span class="op">=</span> <span class="dv">0</span>;</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>  clazz1<span class="op">()</span> <span class="op">{</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>      i <span class="op">=</span> <span class="dv">123</span>;</span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">(</span>nondet<span class="op">)</span> <span class="op">{</span></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a>        j <span class="op">=</span> <span class="dv">456</span>;</span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a>      <span class="co">//non-compliant: [init.all.paths]</span></span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
<div class="sourceCode" id="cb5"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> <span class="op">[[</span><span class="at">Profiles</span><span class="op">::</span><span class="at">enable</span><span class="op">(</span><span class="at">initialization</span><span class="op">)]]</span> clazz2 <span class="op">{</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> i;</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> j;</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>  clazz2<span class="op">()</span> <span class="op">:</span> i<span class="op">(</span>j<span class="op">)</span>, j<span class="op">(</span><span class="dv">42</span><span class="op">)</span> <span class="op">{}</span> <span class="co">//non-compliant: [init.before.read]</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
<div class="sourceCode" id="cb6"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> <span class="op">[[</span><span class="at">Profiles</span><span class="op">::</span><span class="at">enable</span><span class="op">(</span><span class="at">initialization</span><span class="op">)]]</span> clazz3 <span class="op">{</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> i;</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> j;</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>  clazz3<span class="op">()</span> <span class="op">{</span> <span class="co">//compliant, but bad form</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">this</span><span class="op">-&gt;</span>i <span class="op">=</span> <span class="dv">0</span>;</span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">this</span><span class="op">-&gt;</span>j <span class="op">=</span> <span class="dv">42</span>;</span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
<div class="sourceCode" id="cb7"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> pod <span class="op">{</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> i;</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> j;</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> <span class="op">[[</span><span class="at">Profiles</span><span class="op">::</span><span class="at">enable</span><span class="op">(</span><span class="at">initialization</span><span class="op">)]]</span> clazz4 <span class="op">{</span></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>  pod p;</span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a>  clazz4<span class="op">()</span> <span class="op">=</span> <span class="cf">default</span>; <span class="co">//non-compliant: non-initializing default initialization [init.all.paths]</span></span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> <span class="op">[[</span><span class="at">Profiles</span><span class="op">::</span><span class="at">enable</span><span class="op">(</span><span class="at">initialization</span><span class="op">)]]</span> clazz5 <span class="op">{</span></span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a>  pod p<span class="op">{}</span>;</span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true" tabindex="-1"></a>  clazz5<span class="op">()</span> <span class="op">=</span> <span class="cf">default</span>; <span class="co">//compliant, p is value-initialized</span></span>
<span id="cb7-12"><a href="#cb7-12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb7-13"><a href="#cb7-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-14"><a href="#cb7-14" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> <span class="op">[[</span><span class="at">Profiles</span><span class="op">::</span><span class="at">enable</span><span class="op">(</span><span class="at">initialization</span><span class="op">)]]</span> clazz6 <span class="op">{</span></span>
<span id="cb7-15"><a href="#cb7-15" aria-hidden="true" tabindex="-1"></a>  pod podFactory<span class="op">()</span> <span class="op">{</span></span>
<span id="cb7-16"><a href="#cb7-16" aria-hidden="true" tabindex="-1"></a>    pod p;    <span class="co">// non-initializing default initialization</span></span>
<span id="cb7-17"><a href="#cb7-17" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> p;</span>
<span id="cb7-18"><a href="#cb7-18" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb7-19"><a href="#cb7-19" aria-hidden="true" tabindex="-1"></a>  clazz6<span class="op">()</span> <span class="op">:</span> p<span class="op">(</span>podFactory<span class="op">())</span> <span class="op">{}</span> <span class="co">//non-compliant: [only.acceptable.in]</span></span>
<span id="cb7-20"><a href="#cb7-20" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<div class="sourceCode" id="cb8"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> <span class="op">[[</span><span class="at">Profiles</span><span class="op">::</span><span class="at">enable</span><span class="op">(</span><span class="at">initialization</span><span class="op">)]]</span> clazz7 <span class="op">{</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> i;</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> j;</span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>  clazz7<span class="op">(</span><span class="dt">int</span> i<span class="op">)</span> <span class="op">:</span> i<span class="op">(</span>i<span class="op">)</span>, j<span class="op">()</span> <span class="op">{}</span> <span class="co">//compliant, j is value-initialized</span></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
<div class="sourceCode" id="cb9"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> <span class="op">[[</span><span class="at">Profiles</span><span class="op">::</span><span class="at">enable</span><span class="op">(</span><span class="at">initialization</span><span class="op">)]]</span> clazz8 <span class="op">{</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> i;</span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> j;</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>  utility_function<span class="op">()</span> <span class="kw">const</span>;</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>  clazz8<span class="op">(</span><span class="dt">int</span> i<span class="op">)</span> <span class="op">:</span> i<span class="op">(</span>i<span class="op">)</span>, j<span class="op">()</span> <span class="op">{</span></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>    utility_function<span class="op">()</span>;  <span class="co">//non-compliant: [no.args]</span></span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
<div class="sourceCode" id="cb10"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> <span class="op">[[</span><span class="at">Profiles</span><span class="op">::</span><span class="at">enable</span><span class="op">(</span><span class="at">initialization</span><span class="op">)]]</span> clazz9 <span class="op">{</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> i;</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> j;</span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">void</span> mutating<span class="op">(</span><span class="dt">int</span><span class="op">&amp;)</span> <span class="kw">const</span>;</span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>  clazz9<span class="op">(</span><span class="dt">int</span> i<span class="op">)</span> <span class="op">:</span> i<span class="op">(</span>i<span class="op">)</span>, j<span class="op">()</span> <span class="op">{</span></span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a>    mutating<span class="op">(</span>j<span class="op">)</span>;  <span class="co">//non-compliant: [no.args]</span></span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
<div class="sourceCode" id="cb11"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> <span class="op">[[</span><span class="at">Profiles</span><span class="op">::</span><span class="at">enable</span><span class="op">(</span><span class="at">initialization</span><span class="op">)]]</span> clazz10 <span class="op">{</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> i;</span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> j;</span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">void</span> mutating<span class="op">()</span>;</span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a>  clazz10<span class="op">(</span><span class="dt">int</span> i<span class="op">)</span> <span class="op">:</span> i<span class="op">(</span>i<span class="op">)</span>, j<span class="op">()</span> <span class="op">{</span></span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a>    mutating<span class="op">()</span>;  <span class="co">//non-compliant: [no.args]</span></span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb11-8"><a href="#cb11-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
<div class="sourceCode" id="cb12"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> <span class="op">[[</span><span class="at">Profiles</span><span class="op">::</span><span class="at">enable</span><span class="op">(</span><span class="at">initialization</span><span class="op">)]]</span> clazz11 <span class="op">{</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> i;</span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> j;</span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">void</span> mutating<span class="op">()</span> <span class="kw">const</span> <span class="op">{</span></span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> uninit;</span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const_cast</span><span class="op">&lt;</span>clazz11<span class="op">*&gt;(</span><span class="kw">this</span><span class="op">)-&gt;</span>j <span class="op">=</span> uninit;</span>
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb12-8"><a href="#cb12-8" aria-hidden="true" tabindex="-1"></a>  clazz11<span class="op">(</span><span class="dt">int</span> i<span class="op">)</span> <span class="op">:</span> i<span class="op">(</span>i<span class="op">)</span>, j<span class="op">()</span> <span class="op">{</span></span>
<span id="cb12-9"><a href="#cb12-9" aria-hidden="true" tabindex="-1"></a>    mutating<span class="op">()</span>;  <span class="co">//non-compliant: [no.args]</span></span>
<span id="cb12-10"><a href="#cb12-10" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb12-11"><a href="#cb12-11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
<div class="sourceCode" id="cb13"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> <span class="op">[[</span><span class="at">Profiles</span><span class="op">::</span><span class="at">enable</span><span class="op">(</span><span class="at">initialization</span><span class="op">)]]</span> clazz12 <span class="op">{</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>  std<span class="op">::</span>byte<span class="op">*</span> buf <span class="op">[[</span><span class="at">indeterminate</span><span class="op">]]</span>;</span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">size_t</span>    buf_size;</span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> i;</span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a>  clazz12<span class="op">()</span> <span class="op">:</span> i<span class="op">(</span>std<span class="op">::</span>to_integer<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;(</span>buf<span class="op">[</span><span class="dv">0</span><span class="op">]))</span> <span class="op">{}</span> <span class="co">//non-compliant: [only.acceptable.in]</span></span>
<span id="cb13-6"><a href="#cb13-6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
<div class="sourceCode" id="cb14"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> <span class="op">[[</span><span class="at">Profiles</span><span class="op">::</span><span class="at">enable</span><span class="op">(</span><span class="at">initialization</span><span class="op">)]]</span> clazz13 <span class="op">{</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">static</span> <span class="dt">unsigned</span> num_allocations;</span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>  clazz13<span class="op">()</span> <span class="op">{</span></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">++</span>num_allocations; <span class="co">//compliant: [only.acceptable.in]</span></span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a><span class="dt">unsigned</span> clazz13<span class="op">::</span>num_allocations <span class="op">=</span> <span class="dv">0</span>;</span></code></pre></div>
<p>Please note that this profile will mark some correct code as
non-compliant. This is unavoidable.</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> <span class="op">[[</span><span class="at">Profiles</span><span class="op">::</span><span class="at">enable</span><span class="op">(</span><span class="at">initialization</span><span class="op">)]]</span> clazz14 <span class="op">{</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>  std<span class="op">::</span>byte<span class="op">*</span> buf <span class="op">[[</span><span class="at">indeterminate</span><span class="op">]]</span>;</span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">size_t</span>    buf_size;</span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> i;</span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>  clazz14<span class="op">(</span><span class="dt">size_t</span> sz<span class="op">)</span> <span class="op">:</span> buf_size<span class="op">(</span>sz<span class="op">)</span> <span class="op">{</span></span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="op">(</span>sz <span class="op">&gt;</span> <span class="dv">0</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a>      buf <span class="op">=</span> <span class="kw">new</span> std<span class="op">::</span>byte<span class="op">[</span>sz<span class="op">]</span>;</span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a>      std<span class="op">::</span>fill<span class="op">(</span>buf, buf <span class="op">+</span> sz, std<span class="op">::</span>byte<span class="op">{</span><span class="dv">0</span><span class="op">})</span>;</span>
<span id="cb15-9"><a href="#cb15-9" aria-hidden="true" tabindex="-1"></a>      i <span class="op">=</span> std<span class="op">::</span>to_integer<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;(</span>buf<span class="op">[</span><span class="dv">0</span><span class="op">])</span>; <span class="co">//safe, but non-compliant: [only.acceptable.in]</span></span>
<span id="cb15-10"><a href="#cb15-10" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb15-11"><a href="#cb15-11" aria-hidden="true" tabindex="-1"></a>        buf <span class="op">=</span> <span class="kw">nullptr</span>;</span>
<span id="cb15-12"><a href="#cb15-12" aria-hidden="true" tabindex="-1"></a>        i <span class="op">=</span> <span class="op">-</span><span class="dv">1</span>;</span>
<span id="cb15-13"><a href="#cb15-13" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb15-14"><a href="#cb15-14" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb15-15"><a href="#cb15-15" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
<h1 data-number="7" id="templates"><span class="header-section-number">7</span> Templates<a href="#templates" class="self-link"></a></h1>
<p>In the case of templated classes, the property is verified during
template instantiation.</p>
<div class="sourceCode" id="cb16"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> NotAnnotated<span class="op">{</span><span class="co">/**/</span><span class="op">}</span>;</span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="op">[[</span><span class="at">Profiles</span><span class="op">::</span><span class="at">enable</span><span class="op">(</span><span class="at">initialization</span><span class="op">)]]</span> Annotated <span class="op">{</span><span class="co">/**/</span><span class="op">}</span>;</span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-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="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="op">[[</span><span class="at">Profiles</span><span class="op">::</span><span class="at">enable</span><span class="op">(</span><span class="at">initialization</span><span class="op">)]]</span> AnnotatedTemplate <span class="op">{</span></span>
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a>  T field <span class="op">=</span> T<span class="op">()</span>;</span>
<span id="cb16-7"><a href="#cb16-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb16-8"><a href="#cb16-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-9"><a href="#cb16-9" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> foo<span class="op">()</span> <span class="op">{</span></span>
<span id="cb16-10"><a href="#cb16-10" aria-hidden="true" tabindex="-1"></a>  AnnotatedTemplate<span class="op">&lt;</span>NotAnnotated<span class="op">&gt;</span> nat <span class="op">{}</span>; <span class="co">//non-compliant, calling the constructor to a non-verified class</span></span>
<span id="cb16-11"><a href="#cb16-11" aria-hidden="true" tabindex="-1"></a>  AnnotatedTemplate<span class="op">&lt;</span>Annotated<span class="op">&gt;</span>     at <span class="op">{}</span>; <span class="co">//compliant</span></span>
<span id="cb16-12"><a href="#cb16-12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<h1 data-number="8" id="idioms-to-consider"><span class="header-section-number">8</span> Idioms to Consider<a href="#idioms-to-consider" class="self-link"></a></h1>
<h2 data-number="8.1" id="non-constructor-delegating"><span class="header-section-number">8.1</span> Non-Constructor Delegating<a href="#non-constructor-delegating" class="self-link"></a></h2>
<p>A recent SG23 mailing list discussion highlighted that delegating
initialization to a non-constructor member function is idiomatic in C++.
Supporting this idiom would make this profile more useful.</p>
<p>The bit of code that triggered the discussion is the following:</p>
<div class="sourceCode" id="cb17"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a>basic_string<span class="op">(</span><span class="kw">const</span> _CharT<span class="op">*</span> __s, <span class="kw">const</span> _Alloc<span class="op">&amp;</span> __a <span class="op">=</span> _Alloc<span class="op">())</span></span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a><span class="op">:</span> _M_dataplus<span class="op">(</span>_M_local_data<span class="op">()</span>, __a<span class="op">)</span></span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a>  <span class="co">//...</span></span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a>  _M_construct<span class="op">(</span>__s, __end, forward_iterator_tag<span class="op">())</span>;</span>
<span id="cb17-6"><a href="#cb17-6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>In this case, <code class="sourceCode cpp">_M_local_data<span class="op">()</span></code>
returns a const pointer to a data member
(<code class="sourceCode cpp">_M_local_buf</code>) and passes it to the
<code class="sourceCode cpp">_M_dataplus</code> data member. The
initialization then is done by
<code class="sourceCode cpp">_M_construct</code>. This code would be
reported as violating the safety profile as we specify it in this draft,
since the constructor does not initialize
<code class="sourceCode cpp">_M_dataplus</code> directly.</p>
<p>There are a few solutions to this problem:</p>
<ol type="1">
<li>Force developers to rewrite their code to use delegating
constructors.</li>
<li>Use an on-demand interprocedural analysis that ensures that
initialization happens on all paths in the callee.</li>
<li>A suggestion was to annotate arguments that must be initialized with
<code class="sourceCode cpp"><span class="op">[[</span><span class="at">must_init</span><span class="op">]]</span></code>.</li>
</ol>
<div class="sourceCode" id="cb18"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> DelegatingInit <span class="op">{</span></span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> member;</span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a>  DelegatingInit<span class="op">()</span> <span class="op">{</span></span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a>    internal_init<span class="op">(&amp;</span>member<span class="op">)</span>;</span>
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb18-6"><a href="#cb18-6" aria-hidden="true" tabindex="-1"></a>  internal_init<span class="op">([[</span><span class="at">must_init</span><span class="op">]]</span> <span class="dt">int</span><span class="op">*</span> p<span class="op">)</span>;</span>
<span id="cb18-7"><a href="#cb18-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>This option is less intrusive than option 1, and would be simpler to
verify than option 2, simply because the scope of the analysis becomes
well-bounded. As such, it is worth considering.</p>
<p>Nonetheless, we consider it undesirable for the following
reasons:</p>
<ul>
<li>Adding another attribute is undesirable.</li>
<li>Only explicit parameters can be initialized this way. However,
developers might like to have a general
<code class="sourceCode cpp">initialize<span class="op">()</span></code>
member function.</li>
<li>Functions with the <code class="sourceCode cpp"><span class="op">[[</span><span class="at">must_init</span><span class="op">]]</span></code>
attribute can delegate further to other <code class="sourceCode cpp"><span class="op">[[</span><span class="at">must_init</span><span class="op">]]</span></code>
functions, this can lead to recursion.</li>
</ul>
<h2 data-number="8.2" id="discipline-with-const-and-const-parameters"><span class="header-section-number">8.2</span> Discipline with <code class="sourceCode cpp"><span class="kw">const</span><span class="op">&amp;</span></code>
and <code class="sourceCode cpp"><span class="kw">const</span><span class="op">*</span></code>
Parameters<a href="#discipline-with-const-and-const-parameters" class="self-link"></a></h2>
<p>While C++ allows to strip
<code class="sourceCode cpp"><span class="kw">const</span></code>-ness
through casting, this practice is uncommon. It would be preferable to
allow function calls in constructors pass acceptable inputs by
<code class="sourceCode cpp"><span class="kw">const</span></code>
reference or
<code class="sourceCode cpp"><span class="kw">const</span></code>
pointer. However, we need a way to ensure that the callees are do not
use shenanigans allowing them to modify the state of acceptable
inputs.</p>
<p>There are a few solutions to this problem:</p>
<ol type="1">
<li>Require that all member functions in verified classes enforce a
variant of criterion [effective.const].</li>
<li>Add an attribute (e.g. <code class="sourceCode cpp"><span class="op">[[</span><span class="at">const_is_const</span><span class="op">]]</span></code>)
at the function declaration that indicates to the analyzer that a
variant of criterion [effective.const] must be verified for the
function.</li>
<li>Require that all functions within the scope of the profile attribute
be prohibited from using mechanisms that remove
<code class="sourceCode cpp"><span class="kw">const</span></code>-ness,
unless they have the novel <code class="sourceCode cpp"><span class="op">[[</span><span class="at">unsafe</span><span class="op">]]</span></code>
attribute.</li>
<li>The verifier could use an interprocedural analysis.</li>
</ol>
<p>Regarding solution 1, there are edge cases with virtual member
functions and we wouldn’t allow verified classes’ constructors to call
non-member functions.</p>
<p>Regarding solution 2, we don’t like adding additional attributes,
which may hamper adoption. It does however keep the analysis simple.</p>
<p>Regarding solution 3, it widens the scope of the profile. While that
is a good thing, it may be challenging to communicate exactly what the
scope is to developers.</p>
<p>Regarding solution 4, it is the most obvious solution, but is
restricted to cases where the call target can be determined accurately.
It would also increase the complexity of the implementation and, in
turn, risk to hamper adoption.</p>
<h2 data-number="8.3" id="non-initializing-default-initialization"><span class="header-section-number">8.3</span> Non-Initializing Default
Initialization<a href="#non-initializing-default-initialization" class="self-link"></a></h2>
<p>Many restrictions stem from the fact that default initialization
sometimes mean that no initialization is performed ([dcl.init]).
Prohibiting its use in functions called from verified classes’
constructors could be beneficial. However, it expands the scope of the
profile.</p>
<h1 data-number="9" id="divergences-from-p3274r0"><span class="header-section-number">9</span> Divergences from <span class="citation" data-cites="P3274R0">[<a href="https://wg21.link/p3274r0" role="doc-biblioref">P3274R0</a>]</span><a href="#divergences-from-p3274r0" class="self-link"></a></h1>
<p>This draft materially deviates from <span class="citation" data-cites="P3274R0">[<a href="https://wg21.link/p3274r0" role="doc-biblioref">P3274R0</a>]</span> in the following ways:</p>
<ul>
<li>We do not assume that all default constructors are initializing data
members.</li>
<li>We do not require that data members are initialized only once, since
multiple assignments are not a correctness issue.</li>
<li>We do not take position on implicit initialization and whether it is
error-prone.</li>
<li>We added the profile attribute at the class level, rather than at
the level of the translation unit. As explained above, this is for
making examples more communicative. Our proposal is orthogonal to the
location of the attribute.</li>
</ul>
<h1 data-number="10" id="future-work"><span class="header-section-number">10</span> Future Work<a href="#future-work" class="self-link"></a></h1>
<p>The proposed attribute could be misunderstood to mean that all
variables in all the code in the scope of the attribute are properly
initialized. This may be addressed in a future version of this profile,
or in another profile.</p>
<p>We also observe that profiles imply a constraint on what types can be
used in a template. This hints at a new concept. A future revision of
this paper would explore this further.</p>
<h1 data-number="11" id="conclusion"><span class="header-section-number">11</span> Conclusion<a href="#conclusion" class="self-link"></a></h1>
<p>In this paper, we propose a safety profile that guarantees that any
class affected by the profile attribute will have all its data members
initialized, assuming that the data used for construction is itself
initialized properly. The profile does not depend on the presence of
specific modern C++ features and can thus be applied to legacy code
bases.</p>
<h1 data-number="12" id="straw-polls"><span class="header-section-number">12</span> Straw Polls<a href="#straw-polls" class="self-link"></a></h1>
<p>Q1: Should an attribute be used to exempt data members from
initialization?</p>
<p>Q2: Should specific types be used to exempt data members from
initialization?</p>
<p>Q3: Should this profile handle initialization outside of
constructors?</p>
<p>Q4: If this profile were to handle initialization outside of
constructors, should the profile rely on an attribute on parameters that
indicates what the function is responsible for initializing?</p>
<p>Q5: If this profile were to allow verified inputs to be passed by
<code class="sourceCode cpp"><span class="kw">const</span><span class="op">&amp;</span></code>
or <code class="sourceCode cpp"><span class="kw">const</span><span class="op">*</span></code>,
how would it ensure that they are no tampered with?</p>
<p>Q6: For a given scope of applicability (e.g. translation unit),
should this profile prohibit the use of default initialization
altogether? Or prohibit the use of default initialization leading to no
initialization?</p>
<p>Q7: Given that this profile does not consider initialization at
large, should we rename it to
<code class="sourceCode cpp">class_initialization</code>?</p>
<h1 data-number="13" id="bibliography"><span class="header-section-number">13</span> References<a href="#bibliography" class="self-link"></a></h1>
<div id="refs" class="references csl-bib-body hanging-indent" data-entry-spacing="1" role="list">
<div id="ref-CertCPP" class="csl-entry" role="listitem">
[CERT] SEI CERT. 2016. SEI CERT C++ Coding Standard. <a href="https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=88046682"><div class="csl-block">https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=88046682</div></a>
</div>
<div id="ref-MisraCPP2023" class="csl-entry" role="listitem">
[MISRA] The MISRA Consortium and Chris Tapp. 2023. MISRA C++:2023:
Guidelines for the use of C++17 in critical systems. <a href="https://misra.org.uk/misra-cpp2023-released-including-hardcopy/"><div class="csl-block">https://misra.org.uk/misra-cpp2023-released-including-hardcopy/</div></a>
</div>
<div id="ref-P2795R5" class="csl-entry" role="listitem">
[P2795R5] Thomas Köppe. 2024-03-22. Erroneous behaviour for
uninitialized reads. <a href="https://wg21.link/p2795r5"><div class="csl-block">https://wg21.link/p2795r5</div></a>
</div>
<div id="ref-P3274R0" class="csl-entry" role="listitem">
[P3274R0] Bjarne Stroustrup. 2024-05-10. A framework for Profiles
development. <a href="https://wg21.link/p3274r0"><div class="csl-block">https://wg21.link/p3274r0</div></a>
</div>
</div>
</div>
</div>
</body>
</html>
