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

hyphens: auto;
line-height: 1.35;
text-align: justify;
}
@media screen and (max-width: 30em) {
body {
margin: 1.5em;
}
}
div.wrapper {
max-width: 60em;
margin: auto;
}
ul {
list-style-type: none;
padding-left: 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">A Safety Profile Verifying
Initialization</h1>
<table style="border:none;float:right">
  <tr>
    <td>Document #:</td>
    <td>P3402R2</td>
  </tr>
  <tr>
    <td>Date:</td>
    <td>2025-01-13</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Project:</td>
    <td>Programming Language C++</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Audience:</td>
    <td>
      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<span></span></a></li>
<li><a href="#introduction" id="toc-introduction"><span class="toc-section-number">2</span> Introduction<span></span></a>
<ul>
<li><a href="#industry-demand" id="toc-industry-demand"><span class="toc-section-number">2.1</span> Industry
Demand<span></span></a></li>
</ul></li>
<li><a href="#design-objectives" id="toc-design-objectives"><span class="toc-section-number">3</span> Design Objectives<span></span></a>
<ul>
<li><a href="#main-objective" id="toc-main-objective"><span class="toc-section-number">3.1</span> Main
Objective<span></span></a></li>
<li><a href="#profile-quality-objectives" id="toc-profile-quality-objectives"><span class="toc-section-number">3.2</span> Profile Quality
Objectives<span></span></a></li>
<li><a href="#non-objectives" id="toc-non-objectives"><span class="toc-section-number">3.3</span>
Non-objectives<span></span></a></li>
</ul></li>
<li><a href="#definitions" id="toc-definitions"><span class="toc-section-number">4</span> Definitions<span></span></a></li>
<li><a href="#exemptions" id="toc-exemptions"><span class="toc-section-number">5</span> Exemptions<span></span></a></li>
<li><a href="#interactions-with-non-verified-code" id="toc-interactions-with-non-verified-code"><span class="toc-section-number">6</span> Interactions with Non-Verified
Code<span></span></a></li>
<li><a href="#constraints-on-code" id="toc-constraints-on-code"><span class="toc-section-number">7</span> Constraints on Code<span></span></a>
<ul>
<li><a href="#general-constraints" id="toc-general-constraints"><span class="toc-section-number">7.1</span> General
Constraints<span></span></a></li>
<li><a href="#verified-globals" id="toc-verified-globals"><span class="toc-section-number">7.2</span> Verified
Globals<span></span></a></li>
<li><a href="#verified-classes" id="toc-verified-classes"><span class="toc-section-number">7.3</span> Verified
Classes<span></span></a></li>
<li><a href="#verified-functions" id="toc-verified-functions"><span class="toc-section-number">7.4</span> Verified
Functions<span></span></a>
<ul>
<li><a href="#for-all-verified-functions" id="toc-for-all-verified-functions"><span class="toc-section-number">7.4.1</span> For All Verified
Functions<span></span></a></li>
<li><a href="#for-constructors-of-verified-classes" id="toc-for-constructors-of-verified-classes"><span class="toc-section-number">7.4.2</span> For Constructors of Verified
Classes<span></span></a></li>
</ul></li>
</ul></li>
<li><a href="#templates" id="toc-templates"><span class="toc-section-number">8</span> Templates<span></span></a></li>
<li><a href="#discussion" id="toc-discussion"><span class="toc-section-number">9</span> Discussion<span></span></a>
<ul>
<li><a href="#alternative-to-stdverified_cast" id="toc-alternative-to-stdverified_cast"><span class="toc-section-number">9.1</span> Alternative to <code class="sourceCode cpp">std<span class="op">::</span>verified_cast</code><span></span></a></li>
<li><a href="#necessity-of-no.reassign" id="toc-necessity-of-no.reassign"><span class="toc-section-number">9.2</span> Necessity of
<code class="sourceCode cpp">no<span class="op">.</span>reassign</code>?<span></span></a></li>
<li><a href="#non-constructor-delegating" id="toc-non-constructor-delegating"><span class="toc-section-number">9.3</span> Non-Constructor
Delegating<span></span></a></li>
<li><a href="#divergences-from-p3274r0" id="toc-divergences-from-p3274r0"><span class="toc-section-number">9.4</span> Divergences from <span class="citation" data-cites="P3274R0">[<span>P3274R0</span>]</span><span></span></a></li>
<li><a href="#overlap-with-p3081r1" id="toc-overlap-with-p3081r1"><span class="toc-section-number">9.5</span> Overlap with <span class="citation" data-cites="P3081R1">[<span>P3081R1</span>]</span><span></span></a></li>
<li><a href="#overlap-with-p1179r1" id="toc-overlap-with-p1179r1"><span class="toc-section-number">9.6</span> Overlap with <span class="citation" data-cites="P1179R1">[<span>P1179R1</span>]</span><span></span></a></li>
<li><a href="#risks-of-inconsistency" id="toc-risks-of-inconsistency"><span class="toc-section-number">9.7</span> Risks of
Inconsistency<span></span></a></li>
</ul></li>
<li><a href="#future-work" id="toc-future-work"><span class="toc-section-number">10</span> Future Work<span></span></a></li>
<li><a href="#conclusion" id="toc-conclusion"><span class="toc-section-number">11</span> Conclusion<span></span></a></li>
<li><a href="#straw-polls-concluded" id="toc-straw-polls-concluded"><span class="toc-section-number">12</span> Straw Polls
Concluded<span></span></a></li>
<li><a href="#straw-polls-to-consider" id="toc-straw-polls-to-consider"><span class="toc-section-number">13</span> Straw Polls To
Consider<span></span></a></li>
<li><a href="#revision-history" id="toc-revision-history"><span class="toc-section-number">14</span> Revision
History<span></span></a></li>
<li><a href="#bibliography" id="toc-bibliography"><span class="toc-section-number">15</span> References<span></span></a></li>
</ul>
</div>
<h1 data-number="1" id="abstract"><span class="header-section-number">1</span> Abstract<a href="#abstract" class="self-link"></a></h1>
<p>We propose an attribute that specifies that ensures initialization of
variables to determinate values, under a limited set of assumptions.
This profile’s sole objective is to prevent undefined or erroneous
behavior related to a lack of initialization. This safety profile
prohibits some C++ features, and restricts constructors. 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.</p>
<p>In this paper, we propose the
<code class="sourceCode cpp">initialization</code> profile, which
operates at the ‘enforce’ level (<span class="citation" data-cites="P3081R1">[<a href="https://wg21.link/P3081R1" role="doc-biblioref">P3081R1</a>]</span>), and provides guarantees about
variables’ initialization.</p>
<p>The examples in this paper assume that the profile is enabled at the
‘enforce’ level, unless annotated otherwise.</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> 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">//profile-rejected:, 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> 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></code></pre></div>
<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>
<h1 data-number="3" id="design-objectives"><span class="header-section-number">3</span> Design Objectives<a href="#design-objectives" class="self-link"></a></h1>
<h2 data-number="3.1" id="main-objective"><span class="header-section-number">3.1</span> Main Objective<a href="#main-objective" class="self-link"></a></h2>
<p>The main objective of is profile is to eliminate the risk of
undefined/erroneous behavior due to uninitialized memory, with the
following assumptions:</p>
<ul>
<li>Inputs to verified code are initialized to determinate values</li>
<li>There are no dandling pointers or references (i.e. the <code class="sourceCode cpp">std<span class="op">::</span>lifetime</code>
profile is enabled)</li>
<li>There is no
<code class="sourceCode cpp"><span class="kw">const</span></code>ness
stripping (i.e. the
<code class="sourceCode cpp">std<span class="op">::</span>type</code>
profile is enabled)</li>
<li>The programmer uses the exemption mechanisms in a manner that’s
memory-safe.</li>
</ul>
<h2 data-number="3.2" id="profile-quality-objectives"><span class="header-section-number">3.2</span> Profile Quality Objectives<a href="#profile-quality-objectives" class="self-link"></a></h2>
<p>In addition, we have following non-functional objectives:</p>
<p>Simplicity of specification and use:</p>
<ul>
<li>the set of rules should be small, with few exceptions.</li>
<li>minimal or no annotations</li>
</ul>
<p>Simplicity of verification:</p>
<ul>
<li>Verification should be done by intraprocedural analysis.</li>
<li>Verification should not require dataflow analysis.</li>
</ul>
<p>Industrial applicability</p>
<ul>
<li>This profile should be useable on older code bases in an incremental
manner.</li>
<li>The profile should rely on C++11 language features, except for any
attribute specified in a later version of C++.</li>
<li>Verified code should be able to interact with non-verified code in a
safe manner.</li>
</ul>
<h2 data-number="3.3" id="non-objectives"><span class="header-section-number">3.3</span> Non-objectives<a href="#non-objectives" class="self-link"></a></h2>
<p>This profile does not address the dandling pointer and overrun
problems.</p>
<h1 data-number="4" id="definitions"><span class="header-section-number">4</span> Definitions<a href="#definitions" class="self-link"></a></h1>
<p>A <em>verified global</em> is a variable with static storage duration
(<span>6.7.6.2
<a href="https://wg21.link/basic.stc.static">[basic.stc.static]</a></span>)
or thread storage duration (<span>6.7.6.3
<a href="https://wg21.link/basic.stc.thread">[basic.stc.thread]</a></span>)
which are affected by the profile attribute that is not exempted from
verification.</p>
<p>A <em>verified class</em> is a class that is affected by the profile
attribute.</p>
<p>A <em>verified function</em> is a function affected by the profile
attribute. This includes the member functions of a verified class, and
lambdas defined by a verified function.</p>
<p>A <em>verified data member</em> is a non-static data member of a
verified class that is not exempted from verification.</p>
<p>A <em>verified variable</em> is a verified global, a verified data
member, a variable with automatic storage duration in a verified
function, or a verified function’s formal parameters.</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 (<span>9.3.4.6
<a href="https://wg21.link/dcl.fct">[dcl.fct]</a></span>).</p>
<p><em>Acceptable inputs</em> are:</p>
<ol type="1">
<li>The non-exempt transitive closure of reachable verified
variables</li>
<li>Manifestly constant-evaluated expressions (<span>7.7
<a href="https://wg21.link/expr.const">[expr.const]</a></span>)</li>
<li>Object Parameters</li>
<li>Arithmetic operations whose operands are the above (except pointer
arithmetic)</li>
<li>Return values of verified functions when the arguments of the
function call are all acceptable inputs.</li>
<li>Return values of <code class="sourceCode cpp">std<span class="op">::</span>verified_cast</code>.</li>
</ol>
<p>The <em>non-exempt transitive closure</em> of X means the set of
symbols that are reachable from X using built-in the dot and arrow
operators, and which include any symbol exempt from verification</p>
<p>For instance:</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> S <span class="op">{</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> b;</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>  OtherStruct<span class="op">*</span> c;</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> <span class="op">*</span> exempted <span class="op">[[</span><span class="at">indeterminate</span><span class="op">]]</span>;</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> <span class="op">*</span> non_exempted;</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>  OtherStruct exempted_struct <span class="op">[[</span><span class="at">indeterminate</span><span class="op">]]</span>;</span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> verified_function<span class="op">(</span>S s<span class="op">)</span> <span class="op">{</span></span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a>  <span class="kw">auto</span> a <span class="op">=</span> s;                                  <span class="co">//acceptable</span></span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a>  <span class="kw">auto</span> b <span class="op">=</span> s<span class="op">.</span>b;                                <span class="co">//acceptable</span></span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a>  <span class="kw">auto</span> c <span class="op">=</span> s<span class="op">-&gt;</span>c<span class="op">-&gt;</span>c1<span class="op">.</span>c2<span class="op">()</span>;                      <span class="co">//acceptable if c2 is a verified function</span></span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a>  <span class="kw">auto</span> d <span class="op">=</span> s<span class="op">-&gt;</span>exempted;                        <span class="co">//not acceptable</span></span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true" tabindex="-1"></a>  <span class="kw">auto</span> e <span class="op">=</span> s<span class="op">-&gt;</span>non_exempted<span class="op">[</span><span class="dv">32</span><span class="op">]</span>;                <span class="co">//not acceptable</span></span>
<span id="cb2-15"><a href="#cb2-15" aria-hidden="true" tabindex="-1"></a>  <span class="kw">auto</span> f <span class="op">=</span> verified_cast<span class="op">(</span>s<span class="op">-&gt;</span>non_exempted<span class="op">[</span><span class="dv">32</span><span class="op">])</span>; <span class="co">//acceptable</span></span>
<span id="cb2-16"><a href="#cb2-16" aria-hidden="true" tabindex="-1"></a>  <span class="kw">auto</span> g <span class="op">=</span> <span class="op">*</span>s<span class="op">-&gt;</span>non_exempted;                   <span class="co">//not acceptable</span></span>
<span id="cb2-17"><a href="#cb2-17" aria-hidden="true" tabindex="-1"></a>  <span class="kw">auto</span> h <span class="op">=</span> <span class="op">&amp;</span>s<span class="op">.</span>b;                               <span class="co">//not acceptable</span></span>
<span id="cb2-18"><a href="#cb2-18" aria-hidden="true" tabindex="-1"></a>  <span class="kw">auto</span> i <span class="op">=</span> s<span class="op">.</span>exempted_struct<span class="op">.</span>c1;               <span class="co">//not acceptable</span></span>
<span id="cb2-19"><a href="#cb2-19" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Note: The use of built-in 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, unless it is used within <code class="sourceCode cpp">std<span class="op">::</span>verified_cast<span class="op">()</span></code>.
While we can ensure that a memory region is initialized, the program
could still overrun the buffer.</p>
<h1 data-number="5" id="exemptions"><span class="header-section-number">5</span> Exemptions<a href="#exemptions" class="self-link"></a></h1>
<p>Developers could exempt variables 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="cb3"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> HighPerformance <span class="op">{</span></span>
<span id="cb3-2"><a href="#cb3-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="cb3-3"><a href="#cb3-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="cb3-4"><a href="#cb3-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="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
<h1 data-number="6" id="interactions-with-non-verified-code"><span class="header-section-number">6</span> Interactions with Non-Verified
Code<a href="#interactions-with-non-verified-code" class="self-link"></a></h1>
<p>Verified variables can be passed to non-verified functions by copy.
In addition, verified variables can be initialized or assigned with
non-verified data through <code class="sourceCode cpp">std<span class="op">::</span>verified_cast</code>.
This is similar to the Rust <code class="sourceCode cpp">unsafe</code>
expression.</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="op">[[</span><span class="at">profiles</span><span class="op">::</span><span class="at">suppress</span><span class="op">(</span><span class="at">std</span><span class="op">::</span><span class="at">initialization</span><span class="op">)]]</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> non_verified<span class="op">(</span><span class="dt">int</span> a<span class="op">)</span>;</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><span class="dt">int</span> verified_var1 <span class="op">[[</span><span class="at">profiles</span><span class="op">::</span><span class="at">suppress</span><span class="op">(</span><span class="at">std</span><span class="op">::</span><span class="at">initialization</span><span class="op">)]]</span> <span class="op">=</span> <span class="co">/**/</span>;</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> verified_var2 <span class="op">=</span> std<span class="op">::</span>verified_cast<span class="op">(</span>non_verified<span class="op">(</span>verified_var1<span class="op">))</span>; </span></code></pre></div>
<h1 data-number="7" id="constraints-on-code"><span class="header-section-number">7</span> Constraints on Code<a href="#constraints-on-code" class="self-link"></a></h1>
<p>The following constraints must be satisfied by all code under the
purview of that profile, except</p>
<ul>
<li>Program constructs that are argument to <code class="sourceCode cpp">std<span class="op">::</span>verified_cast</code></li>
<li>Program constructs not subject to being profile-rejected (as
mentioned in <code class="sourceCode cpp"><span class="op">[</span>dcl<span class="op">.</span>attr<span class="op">.</span>profile<span class="op">]</span></code>
in <span class="citation" data-cites="P3081R1">[<a href="https://wg21.link/P3081R1" role="doc-biblioref">P3081R1</a>]</span>).</li>
<li>Program constructs subject to being profile-rejected that are not
potentially-evaluated (<span>7.2.3
<a href="https://wg21.link/expr.context">[expr.context]</a></span>).</li>
</ul>
<p>Otherwise, the translation unit is profile-rejected.</p>
<h2 data-number="7.1" id="general-constraints"><span class="header-section-number">7.1</span> General Constraints<a href="#general-constraints" class="self-link"></a></h2>
<p>For all verified variables the following constraints apply:</p>
<ul>
<li><code class="sourceCode cpp">general<span class="op">.</span>always<span class="op">.</span>init</code>
Default initialization that result in no initialization (<span>9.4
<a href="https://wg21.link/dcl.init">[dcl.init]</a></span>) is
prohibited. This rule also applies to arrays and dynamically-allocated
arrays (<span>7.6.2.8
<a href="https://wg21.link/expr.new">[expr.new]</a></span>).</li>
<li><code class="sourceCode cpp">general<span class="op">.</span>verif<span class="op">.</span>init</code>
Verified variables can only be initialized by acceptable inputs.
Likewise, when verified variables are the target of assignments, the
assigned value must be a verified input.</li>
<li><code class="sourceCode cpp">general<span class="op">.</span>type</code>
Verified variables’ type can only be PODs and verified classes, or
pointers or references thereof.</li>
</ul>
<p>Examples:</p>
<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> pod <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><span class="op">}</span>;</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> DefaultDoesNotInitialize <span class="op">{</span></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>  pod p;</span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>  DefaultDoesNotInitialize<span class="op">()</span> <span class="op">=</span> <span class="cf">default</span>; <span class="co">//profile-rejected: general.always.init</span></span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a>pod podFactory<span class="op">()</span> <span class="op">{</span></span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a>  pod p;    <span class="co">// profile-rejected: general.always.init</span></span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> p;</span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb5-14"><a href="#cb5-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-15"><a href="#cb5-15" aria-hidden="true" tabindex="-1"></a><span class="op">[[</span><span class="at">profiles</span><span class="op">::</span><span class="at">suppress</span><span class="op">(</span><span class="at">std</span><span class="op">::</span><span class="at">initialization</span><span class="op">)]]</span></span>
<span id="cb5-16"><a href="#cb5-16" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> non_verified_function<span class="op">()</span>;</span>
<span id="cb5-17"><a href="#cb5-17" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> InitsWithNonVerified <span class="op">{</span></span>
<span id="cb5-18"><a href="#cb5-18" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> _i;</span>
<span id="cb5-19"><a href="#cb5-19" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> _j;</span>
<span id="cb5-20"><a href="#cb5-20" aria-hidden="true" tabindex="-1"></a>  InitsWithNonVerified<span class="op">(</span><span class="dt">int</span> <span class="op">&amp;</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>non_verified_function<span class="op">())</span> <span class="co">//profile-rejected: general.verif.init</span></span>
<span id="cb5-21"><a href="#cb5-21" aria-hidden="true" tabindex="-1"></a>  <span class="op">{}</span></span>
<span id="cb5-22"><a href="#cb5-22" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb5-23"><a href="#cb5-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-24"><a href="#cb5-24" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> UnsafeUpdateArg<span class="op">(</span>pod<span class="op">&amp;</span> p<span class="op">)</span> <span class="op">{</span></span>
<span id="cb5-25"><a href="#cb5-25" aria-hidden="true" tabindex="-1"></a>    p<span class="op">.</span>i <span class="op">=</span> non_verified_function<span class="op">()</span>; <span class="co">//profile-rejected: general.verif.init</span></span>
<span id="cb5-26"><a href="#cb5-26" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb5-27"><a href="#cb5-27" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-28"><a href="#cb5-28" 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">suppress</span><span class="op">(</span><span class="at">std</span><span class="op">::</span><span class="at">initialization</span><span class="op">)]]</span> UnverifiedClass <span class="op">{</span> <span class="co">/**/</span> <span class="op">}</span>;</span>
<span id="cb5-29"><a href="#cb5-29" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-30"><a href="#cb5-30" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> non_verified_in<span class="op">(</span><span class="kw">const</span> UnverifiedClass <span class="op">&amp;</span>uc<span class="op">)</span> <span class="op">{</span> <span class="co">//profile-rejected: general.type</span></span>
<span id="cb5-31"><a href="#cb5-31" aria-hidden="true" tabindex="-1"></a>  <span class="co">//...</span></span>
<span id="cb5-32"><a href="#cb5-32" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<h2 data-number="7.2" id="verified-globals"><span class="header-section-number">7.2</span> Verified Globals<a href="#verified-globals" class="self-link"></a></h2>
<p>Variables with either static storage duration (<span>6.7.6.2
<a href="https://wg21.link/basic.stc.static">[basic.stc.static]</a></span>
- including static data members (<span>11.4.9.3
<a href="https://wg21.link/class.static.data">[class.static.data]</a></span>)
in a verified class) or thread storage duration (<span>6.7.6.3
<a href="https://wg21.link/basic.stc.thread">[basic.stc.thread]</a></span>)
are guaranteed to be initialized with constant initialization
(<span>6.9.3.2
<a href="https://wg21.link/basic.start.static">[basic.start.static]</a></span>).
However, they can be reassigned with dynamic initialization
(<span>6.9.3.3
<a href="https://wg21.link/basic.start.dynamic">[basic.start.dynamic]</a></span>).</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="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> GetsCorrupted <span class="op">{</span></span>
<span id="cb6-2"><a href="#cb6-2" 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="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> thefield;</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> Wrapper <span class="op">{</span></span>
<span id="cb6-7"><a href="#cb6-7" 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="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">static</span> GetsCorrupted wrapped;</span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true" tabindex="-1"></a><span class="op">[[</span><span class="at">profiles</span><span class="op">::</span><span class="at">suppress</span><span class="op">(</span><span class="at">std</span><span class="op">::</span><span class="at">initialization</span><span class="op">)]]</span></span>
<span id="cb6-12"><a href="#cb6-12" aria-hidden="true" tabindex="-1"></a>GetsCorrupted corruptingFactory<span class="op">()</span> <span class="op">{</span></span>
<span id="cb6-13"><a href="#cb6-13" aria-hidden="true" tabindex="-1"></a>    GetsCorrupted ret<span class="op">{}</span>;  <span class="co">//All initialized, good</span></span>
<span id="cb6-14"><a href="#cb6-14" 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="cb6-15"><a href="#cb6-15" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> ret;</span>
<span id="cb6-16"><a href="#cb6-16" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb6-17"><a href="#cb6-17" 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">//profile-rejected: global.static.init, general.verif.init</span></span></code></pre></div>
<p>The use of verified functions improve the picture, but initialization
order issues remain:</p>
<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">extern</span> <span class="dt">int</span> externInt;</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> readsExtern<span class="op">()</span> <span class="op">{</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> externInt; <span class="co">//compliant</span></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="dt">int</span> globalIntInitWithVerifFunc <span class="op">=</span> readsExtern<span class="op">()</span>; <span class="co">//profile-rejected: global.static.init</span></span></code></pre></div>
<p>For all variables with static storage duration and thread storage
duration affected by this profile, the following constraint applies:</p>
<ul>
<li><code class="sourceCode cpp">global<span class="op">.</span><span class="kw">static</span><span class="op">.</span>init</code>
Verified globals can only be initialized using constant or zero
initialization.</li>
</ul>
<h2 data-number="7.3" id="verified-classes"><span class="header-section-number">7.3</span> Verified Classes<a href="#verified-classes" class="self-link"></a></h2>
<p>All verified classes must satisfy the following property:</p>
<ul>
<li><code class="sourceCode cpp">base<span class="op">.</span>are<span class="op">.</span>verified</code>
All base classes of verified classes must be verified classes.</li>
</ul>
<p>Example:</p>
<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="co">//Not a verified class, but would be compliant if it were</span></span>
<span id="cb8-2"><a href="#cb8-2" 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">suppress</span><span class="op">(</span><span class="at">std</span><span class="op">::</span><span class="at">initialization</span><span class="op">)]]</span> NotVerifiedBaseClass <span class="op">{</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> i <span class="op">=</span> <span class="dv">0</span>;</span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>  NotVerifiedBaseClass<span class="op">()</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> VerifiedDerivedClass <span class="op">:</span> <span class="kw">public</span> NotVerifiedBaseClass <span class="op">{</span></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> j;</span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a>  VerifiedDerivedClass<span class="op">()</span> <span class="op">:</span> NotVerifiedBaseClass<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">//profile-rejected: base.are.verified</span></span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
<h2 data-number="7.4" id="verified-functions"><span class="header-section-number">7.4</span> Verified Functions<a href="#verified-functions" class="self-link"></a></h2>
<h3 data-number="7.4.1" id="for-all-verified-functions"><span class="header-section-number">7.4.1</span> For All Verified Functions<a href="#for-all-verified-functions" class="self-link"></a></h3>
<p>All verified functions must also satisfy the following
properties:</p>
<ul>
<li><p><code class="sourceCode cpp">restrict<span class="op">.</span>returns</code>
The function can only return an acceptable input, except for a reference
or a pointer to a local variable.
<!-- The above should cover global reaffectations --></p></li>
<li><p><code class="sourceCode cpp">no<span class="op">.</span>ref<span class="op">.</span>args</code>
Acceptable inputs can be passed to functions as follows:</p>
<ul>
<li>Verified functions: copy, reference, pointer</li>
<li>Non-verified functions: copy, const reference, const pointer</li>
</ul></li>
</ul>
<p><!--* [no.addrof] The address of acceptable inputs cannot be obtained. --></p>
<p>Note: <code class="sourceCode cpp">restrict<span class="op">.</span>returns</code>
implies that lambdas defined in a verified function cannot be
returned.</p>
<p>Examples:</p>
<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="dt">void</span> SafeUpdateArg<span class="op">(</span>pod<span class="op">&amp;</span> p<span class="op">)</span> <span class="op">{</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>    p<span class="op">.</span>i <span class="op">=</span> verified_function<span class="op">()</span>;  <span class="co">//Compliant</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> verified_uses_unverified_compliant<span class="op">(</span><span class="dt">int</span> i<span class="op">)</span> <span class="op">{</span></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> tmp <span class="op">=</span> verified_cast<span class="op">(</span>non_verified_function<span class="op">())</span>; <span class="co">//Compliant</span></span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> i <span class="op">*</span> tmp;</span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a><span class="op">[[</span><span class="at">profiles</span><span class="op">::</span><span class="at">suppress</span><span class="op">(</span><span class="at">std</span><span class="op">::</span><span class="at">initialization</span><span class="op">)]]</span></span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> non_verified_function<span class="op">(</span><span class="dt">int</span><span class="op">&amp;</span> mutate<span class="op">)</span>;</span>
<span id="cb9-12"><a href="#cb9-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-13"><a href="#cb9-13" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> CallsNonVerifiedWithReference <span class="op">{</span></span>
<span id="cb9-14"><a href="#cb9-14" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> _i;</span>
<span id="cb9-15"><a href="#cb9-15" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> _j;</span>
<span id="cb9-16"><a href="#cb9-16" aria-hidden="true" tabindex="-1"></a>  CallsNonVerifiedWithReference<span class="op">(</span><span class="dt">int</span> <span class="op">&amp;</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-17"><a href="#cb9-17" aria-hidden="true" tabindex="-1"></a>    non_verified_function<span class="op">(</span>i<span class="op">)</span>;  <span class="co">//profile-rejected: no.ref.args</span></span>
<span id="cb9-18"><a href="#cb9-18" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb9-19"><a href="#cb9-19" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
<h3 data-number="7.4.2" id="for-constructors-of-verified-classes"><span class="header-section-number">7.4.2</span> For Constructors of Verified
Classes<a href="#for-constructors-of-verified-classes" class="self-link"></a></h3>
<p>In addition to the properties that apply to verified functions, all
constructors of a verified class must satisfy the following
properties:</p>
<ul>
<li><code class="sourceCode cpp">init<span class="op">.</span>before<span class="op">.</span>read</code>
All verified data members must be initialized before being read.</li>
<li><code class="sourceCode cpp">init<span class="op">.</span>all</code>
Except for delegating constructors, the constructor must initialize all
verified data members.</li>
<li><code class="sourceCode cpp">init<span class="op">.</span>list</code>
When verified data members must be initialized, the constructor must use
the <em>mem-initializer-list</em> (<span>11.9.3
<a href="https://wg21.link/class.base.init">[class.base.init]</a></span>)
to initialize them.</li>
<li><code class="sourceCode cpp">no<span class="op">.</span>reassign</code>
Constructor bodies may not assign to verified data members.</li>
</ul>
<p>Note regarding
<code class="sourceCode cpp">init<span class="op">.</span>list</code>:
The following data members are exempt from the
<code class="sourceCode cpp">init<span class="op">.</span>list</code>
criteria:</p>
<ul>
<li>is declared with a <em>brace-or-equal-initializer</em> (<span>11.4.1
<a href="https://wg21.link/class.mem.general">[class.mem.general]</a></span>)</li>
<li>is of a type with a default constructor and its ommision from the
<em>mem-initializer-list</em> would result in the use of that default
constructor</li>
</ul>
<p>A data member is considered read whenever it is present in the
function, except when:</p>
<ul>
<li>It is covered by the exceptions covered above.</li>
<li>It is the left operand of a simple assignment (<span>7.6.19
<a href="https://wg21.link/expr.ass">[expr.ass]</a></span>).</li>
</ul>
<p>Note: 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.</p>
<h4 data-number="7.4.2.1" id="compliant-examples"><span class="header-section-number">7.4.2.1</span> Compliant Examples<a href="#compliant-examples" class="self-link"></a></h4>
<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> ValueInitialized <span class="op">{</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>  pod p<span class="op">{}</span>;</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>  ValueInitialized<span class="op">()</span> <span class="op">=</span> <span class="cf">default</span>; <span class="co">//compliant</span></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> InitWithVerifiedReturnValue <span class="op">{</span></span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a>  <span class="kw">static</span> pod podFactory<span class="op">()</span>;</span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a>  InitWithVerifiedReturnValue<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">//compliant</span></span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-11"><a href="#cb10-11" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> WithExemption <span class="op">{</span></span>
<span id="cb10-12"><a href="#cb10-12" 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="cb10-13"><a href="#cb10-13" aria-hidden="true" tabindex="-1"></a>  <span class="dt">size_t</span>    buf_size;</span>
<span id="cb10-14"><a href="#cb10-14" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> i;</span>
<span id="cb10-15"><a href="#cb10-15" aria-hidden="true" tabindex="-1"></a>  WithExemption<span class="op">()</span> <span class="op">:</span> i<span class="op">(</span><span class="dv">0</span><span class="op">)</span>, buf_size<span class="op">(</span><span class="dv">0</span><span class="op">)</span> <span class="op">{}</span> <span class="co">//compliant: buf is not a verified data member</span></span>
<span id="cb10-16"><a href="#cb10-16" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb10-17"><a href="#cb10-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-18"><a href="#cb10-18" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> SafeDefaultInit <span class="op">{</span></span>
<span id="cb10-19"><a href="#cb10-19" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> i;</span>
<span id="cb10-20"><a href="#cb10-20" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> j;</span>
<span id="cb10-21"><a href="#cb10-21" aria-hidden="true" tabindex="-1"></a>  SafeDefaultInit<span class="op">()</span> <span class="op">:</span> i<span class="op">(</span><span class="dv">123</span><span class="op">)</span>, j<span class="op">(</span><span class="dv">456</span><span class="op">)</span> <span class="op">{}</span> <span class="co">//compliant</span></span>
<span id="cb10-22"><a href="#cb10-22" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb10-23"><a href="#cb10-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-24"><a href="#cb10-24" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> ReliesOnDefaultInit <span class="op">{</span></span>
<span id="cb10-25"><a href="#cb10-25" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> i;</span>
<span id="cb10-26"><a href="#cb10-26" aria-hidden="true" tabindex="-1"></a>  SafeDefaultInit sdi;</span>
<span id="cb10-27"><a href="#cb10-27" aria-hidden="true" tabindex="-1"></a>  ReliesOnDefaultInit<span class="op">()</span> <span class="op">:</span> i<span class="op">(</span><span class="dv">123</span><span class="op">)</span> <span class="op">{}</span> <span class="co">//compliant: sdi has a default ctor</span></span>
<span id="cb10-28"><a href="#cb10-28" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb10-29"><a href="#cb10-29" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-30"><a href="#cb10-30" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> MixedInits <span class="op">{</span></span>
<span id="cb10-31"><a href="#cb10-31" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> i;</span>
<span id="cb10-32"><a href="#cb10-32" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> j;</span>
<span id="cb10-33"><a href="#cb10-33" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> z <span class="op">=</span> <span class="dv">0</span>;</span>
<span id="cb10-34"><a href="#cb10-34" aria-hidden="true" tabindex="-1"></a>  MixedInits<span class="op">()</span> <span class="op">:</span> i<span class="op">(</span><span class="dv">123</span><span class="op">)</span>, j<span class="op">(</span><span class="dv">456</span><span class="op">)</span> <span class="op">{}</span> <span class="co">//compliant: verified data members are initialized using either allowed mechanism</span></span>
<span id="cb10-35"><a href="#cb10-35" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb10-36"><a href="#cb10-36" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-37"><a href="#cb10-37" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> WithCallInCtorBody <span class="op">{</span></span>
<span id="cb10-38"><a href="#cb10-38" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> i;</span>
<span id="cb10-39"><a href="#cb10-39" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> j;</span>
<span id="cb10-40"><a href="#cb10-40" aria-hidden="true" tabindex="-1"></a>  <span class="dt">void</span> utility_function<span class="op">()</span> <span class="kw">const</span>;</span>
<span id="cb10-41"><a href="#cb10-41" aria-hidden="true" tabindex="-1"></a>  WithCallInCtorBody<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-42"><a href="#cb10-42" aria-hidden="true" tabindex="-1"></a>    utility_function<span class="op">()</span>;  <span class="co">//compliant: calling a verified function with &#39;this&#39;</span></span>
<span id="cb10-43"><a href="#cb10-43" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb10-44"><a href="#cb10-44" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb10-45"><a href="#cb10-45" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-46"><a href="#cb10-46" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> UpdatesGlobal <span class="op">{</span></span>
<span id="cb10-47"><a href="#cb10-47" aria-hidden="true" tabindex="-1"></a>  <span class="kw">static</span> <span class="dt">unsigned</span> num_allocations;</span>
<span id="cb10-48"><a href="#cb10-48" aria-hidden="true" tabindex="-1"></a>  UpdatesGlobal<span class="op">()</span> <span class="op">{</span></span>
<span id="cb10-49"><a href="#cb10-49" aria-hidden="true" tabindex="-1"></a>    <span class="op">++</span>num_allocations; <span class="co">//compliant: a verified input is updated with the result of an arithmetic operation over verified inputs</span></span>
<span id="cb10-50"><a href="#cb10-50" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb10-51"><a href="#cb10-51" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb10-52"><a href="#cb10-52" aria-hidden="true" tabindex="-1"></a><span class="dt">unsigned</span> UpdatesGlobal<span class="op">::</span>num_allocations <span class="op">=</span> <span class="dv">0</span>;</span>
<span id="cb10-53"><a href="#cb10-53" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-54"><a href="#cb10-54" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> CallsVerifiedNonConst <span class="op">{</span></span>
<span id="cb10-55"><a href="#cb10-55" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> i;</span>
<span id="cb10-56"><a href="#cb10-56" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> j;</span>
<span id="cb10-57"><a href="#cb10-57" aria-hidden="true" tabindex="-1"></a>  <span class="dt">void</span> mutating<span class="op">()</span>;</span>
<span id="cb10-58"><a href="#cb10-58" aria-hidden="true" tabindex="-1"></a>  CallsVerifiedNonConst<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-59"><a href="#cb10-59" aria-hidden="true" tabindex="-1"></a>    mutating<span class="op">()</span>;  <span class="co">//compliant, but could have a redefinition of i or j</span></span>
<span id="cb10-60"><a href="#cb10-60" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb10-61"><a href="#cb10-61" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
<h4 data-number="7.4.2.2" id="profile-rejected-examples"><span class="header-section-number">7.4.2.2</span> Profile-Rejected Examples<a href="#profile-rejected-examples" class="self-link"></a></h4>
<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> WrongOrder <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>  WrongOrder<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">//profile-rejected: init.before.read</span></span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> MissingInit <span class="op">{</span></span>
<span id="cb11-8"><a href="#cb11-8" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> i;</span>
<span id="cb11-9"><a href="#cb11-9" aria-hidden="true" tabindex="-1"></a>  MissingInit<span class="op">()</span> <span class="op">:</span> <span class="op">{}</span> <span class="co">//profile-rejected: init.all</span></span>
<span id="cb11-10"><a href="#cb11-10" 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> InitInCtorBody <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">int</span> z <span class="op">=</span> <span class="dv">0</span>;</span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>  InitInCtorBody<span class="op">()</span> <span class="op">{</span></span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a>      i <span class="op">=</span> <span class="dv">123</span>;</span>
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true" tabindex="-1"></a>      j <span class="op">=</span> <span class="dv">456</span>;</span>
<span id="cb12-8"><a href="#cb12-8" aria-hidden="true" tabindex="-1"></a>      <span class="co">//profile-rejected: init.list</span></span>
<span id="cb12-9"><a href="#cb12-9" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb12-10"><a href="#cb12-10" 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> ReassignInCtor <span class="op">{</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> i;</span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> j;</span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>  ReassignInCtor<span class="op">()</span> <span class="op">:</span> i<span class="op">(</span><span class="dv">123</span><span class="op">)</span>, j<span class="op">(</span><span class="dv">456</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a>    j <span class="op">=</span> verified_function<span class="op">()</span>; <span class="co">// profile-rejected: no.reassign</span></span>
<span id="cb13-6"><a href="#cb13-6" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb13-7"><a href="#cb13-7" 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> CallsNonVerifiedWithFieldReference <span class="op">{</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> _i;</span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> _j;</span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>  CallsNonVerifiedWithFieldReference<span class="op">(</span><span class="dt">int</span> <span class="op">&amp;</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="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a>    non_verified_function<span class="op">(</span>_j<span class="op">)</span>;  <span class="co">//profile-rejected: no.ref.args</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="op">}</span>;</span></code></pre></div>
<h1 data-number="8" id="templates"><span class="header-section-number">8</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="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">class</span> <span class="op">[[</span><span class="at">profiles</span><span class="op">::</span><span class="at">suppress</span><span class="op">(</span><span class="at">std</span><span class="op">::</span><span class="at">initialization</span><span class="op">)]]</span> Suppressed <span class="op">{</span><span class="co">/**/</span><span class="op">}</span>;</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Enforced <span class="op">{</span><span class="co">/**/</span><span class="op">}</span>;</span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-4"><a href="#cb15-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="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Template <span class="op">{</span></span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a>  T field <span class="op">=</span> T<span class="op">()</span>;</span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-9"><a href="#cb15-9" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> foo<span class="op">()</span> <span class="op">{</span></span>
<span id="cb15-10"><a href="#cb15-10" aria-hidden="true" tabindex="-1"></a>  Template<span class="op">&lt;</span>Suppressed<span class="op">&gt;</span> sup <span class="op">{}</span>; <span class="co">//profile-rejected: calling the constructor to a non-verified class</span></span>
<span id="cb15-11"><a href="#cb15-11" aria-hidden="true" tabindex="-1"></a>  Template<span class="op">&lt;</span>Enforced<span class="op">&gt;</span>   enf <span class="op">{}</span>; <span class="co">//compliant</span></span>
<span id="cb15-12"><a href="#cb15-12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<h1 data-number="9" id="discussion"><span class="header-section-number">9</span> Discussion<a href="#discussion" class="self-link"></a></h1>
<h2 data-number="9.1" id="alternative-to-stdverified_cast"><span class="header-section-number">9.1</span> Alternative to <code class="sourceCode cpp">std<span class="op">::</span>verified_cast</code><a href="#alternative-to-stdverified_cast" class="self-link"></a></h2>
<p>In <span class="citation" data-cites="P3081R1">[<a href="https://wg21.link/P3081R1" role="doc-biblioref">P3081R1</a>]</span>, the proposal is to disable a
profile for a given scope (e.g. <code class="sourceCode cpp"><span class="op">[[</span><span class="at">profiles</span><span class="op">::</span><span class="at">suppress</span><span class="op">(...)]]</span></code>),
such as a block. This would be a suitable alternative to <code class="sourceCode cpp">std<span class="op">::</span>verified_cast</code>.</p>
<h2 data-number="9.2" id="necessity-of-no.reassign"><span class="header-section-number">9.2</span> Necessity of
<code class="sourceCode cpp">no<span class="op">.</span>reassign</code>?<a href="#necessity-of-no.reassign" class="self-link"></a></h2>
<p>The
<code class="sourceCode cpp">no<span class="op">.</span>reassign</code>
is not strictly necessary, and might potentially prohibit legitimate use
cases. This rule was suggested by <span class="citation" data-cites="P3274R0">[<a href="https://wg21.link/p3274r0" role="doc-biblioref">P3274R0</a>]</span> but we should reconsider it on
the grounds of putting as few restrictions as possible in order to
achieve our stated goal.</p>
<h2 data-number="9.3" id="non-constructor-delegating"><span class="header-section-number">9.3</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="cb16"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb16-1"><a href="#cb16-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="cb16-2"><a href="#cb16-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="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a>  <span class="co">//...</span></span>
<span id="cb16-5"><a href="#cb16-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="cb16-6"><a href="#cb16-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="cb17"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> DelegatingInit <span class="op">{</span></span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> member;</span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a>  DelegatingInit<span class="op">()</span> <span class="op">{</span></span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a>    internal_init<span class="op">(&amp;</span>member<span class="op">)</span>;</span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb17-6"><a href="#cb17-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="cb17-7"><a href="#cb17-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 specified 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, possibly leading to recursion.</li>
<li>Verifying such an annotated function would require dataflow
analysis.</li>
</ul>
<p>Given the design objectives, we conclude that there is no viable path
to accept non-constructor delegation in this profile.</p>
<h2 data-number="9.4" id="divergences-from-p3274r0"><span class="header-section-number">9.4</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></h2>
<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 take position on implicit initialization and whether it is
error-prone.</li>
</ul>
<h2 data-number="9.5" id="overlap-with-p3081r1"><span class="header-section-number">9.5</span> Overlap with <span class="citation" data-cites="P3081R1">[<a href="https://wg21.link/P3081R1" role="doc-biblioref">P3081R1</a>]</span><a href="#overlap-with-p3081r1" class="self-link"></a></h2>
<p>The rule for Type.6 proposed by <span class="citation" data-cites="P3081R1">[<a href="https://wg21.link/P3081R1" role="doc-biblioref">P3081R1</a>]</span> is identical to rule <code class="sourceCode cpp">general<span class="op">.</span>always<span class="op">.</span>init</code>.
Since this rule is not related to type safety, it belongs more
meaningfully to the initialization profile.</p>
<p>Since this restriction is very desirable, and that <span class="citation" data-cites="P3081R1">[<a href="https://wg21.link/P3081R1" role="doc-biblioref">P3081R1</a>]</span> has a good chance of landing in
C++26, we encourage <span class="citation" data-cites="P3081R1">[<a href="https://wg21.link/P3081R1" role="doc-biblioref">P3081R1</a>]</span> to specify an initialization
profile containing only rule Type.6, which this paper would eventually
build upon.</p>
<h2 data-number="9.6" id="overlap-with-p1179r1"><span class="header-section-number">9.6</span> Overlap with <span class="citation" data-cites="P1179R1">[<a href="https://wg21.link/p1179r1" role="doc-biblioref">P1179R1</a>]</span><a href="#overlap-with-p1179r1" class="self-link"></a></h2>
<p>The rule <code class="sourceCode cpp">restrict<span class="op">.</span>returns</code>
overlaps with the <code class="sourceCode cpp">lifetime</code> safety
profile to some extent (<span class="citation" data-cites="P1179R1">[<a href="https://wg21.link/p1179r1" role="doc-biblioref">P1179R1</a>]</span>). However, it is a sensible
restriction to enforce. In the event that the Committee would prefer to
avoid overlaps between profiles, the rule could be written as
follows:</p>
<ul>
<li><code class="sourceCode cpp">restrict<span class="op">.</span>returns</code>:
The function can only return an acceptable input.</li>
</ul>
<h2 data-number="9.7" id="risks-of-inconsistency"><span class="header-section-number">9.7</span> Risks of Inconsistency<a href="#risks-of-inconsistency" class="self-link"></a></h2>
<p>Different TUs may have different profiles enabled. This could lead to
situations where a TU mistakenly expects a symbol to comply with the
requirements of this profile. Consider the example below, whereby the TU
implementing <code class="sourceCode cpp">foo</code> does so without the
initialization profile. However, another TU requires the initialization
profile, and depends on <code class="sourceCode cpp">foo</code>.</p>
<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="co">//in impl.cpp</span></span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a><span class="op">[[</span><span class="at">profiles</span><span class="op">::</span><span class="at">suppress</span><span class="op">(</span><span class="at">std</span><span class="op">::</span><span class="at">initialization</span><span class="op">)]]</span></span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> foo<span class="op">()</span> <span class="op">{</span> <span class="co">/*…*/</span> <span class="op">}</span></span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a> </span>
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a><span class="co">//in caller.cpp</span></span>
<span id="cb18-6"><a href="#cb18-6" aria-hidden="true" tabindex="-1"></a><span class="op">[[</span><span class="at">profiles</span><span class="op">::</span><span class="at">enforce</span><span class="op">(</span><span class="at">std</span><span class="op">::</span><span class="at">all</span><span class="op">)]]</span></span>
<span id="cb18-7"><a href="#cb18-7" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> foo<span class="op">()</span>;</span>
<span id="cb18-8"><a href="#cb18-8" aria-hidden="true" tabindex="-1"></a> </span>
<span id="cb18-9"><a href="#cb18-9" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> main<span class="op">(</span><span class="dt">int</span> argc, <span class="dt">char</span><span class="op">**</span> argv<span class="op">)</span> <span class="op">{</span></span>
<span id="cb18-10"><a href="#cb18-10" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> foo<span class="op">()</span>;</span>
<span id="cb18-11"><a href="#cb18-11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>There are a few possible solutions, but all of them would pose
challenges to adoption.</p>
<ul>
<li>The profile annotation should not apply to forward declarations. In
this case, TUs using this profile will have to be self-contained.</li>
<li>The profile information should be added to the symbol’s mangled
name, so that a program like the example above would compile, but not
link. Sadly, a linker error of this nature would likely be hard to
troubleshoot.</li>
<li>Allow this profile only to be used in a module, and require that
module enforcement must be consistent between declarations and
implementations when the module is built.</li>
</ul>
<p>The option of a linker error seems to be the lesser evil for the time
being.</p>
<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>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
all code affected by the profile attribute will initialize both local
and global variables to determinate values, 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>
<p>The profile introduces a single new symbol, <code class="sourceCode cpp">std<span class="op">::</span>verified_cast</code>,
which could be implemented as:</p>
<div class="sourceCode" id="cb19"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="kw">namespace</span> std <span class="op">{</span></span>
<span id="cb19-2"><a href="#cb19-2" 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="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a>    T<span class="op">&amp;&amp;</span> verified_cast<span class="op">(</span>T<span class="op">&amp;&amp;</span> i<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> std<span class="op">::</span>forward<span class="op">(</span>i<span class="op">)</span>; <span class="op">}</span></span>
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Thus, developers on legacy code bases that are still using older
versions of the C++ standard could take advantage of this profile,
assuming that they define <code class="sourceCode cpp">std<span class="op">::</span>verified_cast</code>
in their code base.</p>
<h1 data-number="12" id="straw-polls-concluded"><span class="header-section-number">12</span> Straw Polls Concluded<a href="#straw-polls-concluded" class="self-link"></a></h1>
<p>The following straw polls were conducted during the Wrocław 2024
meeting.</p>
<p>POLL: We should promise more SG23 committee time to pursuing this
paper, knowing that our time is scarce and this will leave less time for
other work.</p>
<table>
<thead>
<tr class="header">
<th><div style="text-align:center">
<strong>Favor</strong>
</div></th>
<th><div style="text-align:center">
<strong>Neutral</strong>
</div></th>
<th><div style="text-align:center">
<strong>Against</strong>
</div></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>18</td>
<td>1</td>
<td>0</td>
</tr>
</tbody>
</table>
<p>Strong consensus</p>
<p>POLL: For a given scope of applicability (eg translation unit) should
this profile prohibit the use of default initialization altogether?</p>
<table>
<thead>
<tr class="header">
<th><div style="text-align:center">
<strong>Favor</strong>
</div></th>
<th><div style="text-align:center">
<strong>Neutral</strong>
</div></th>
<th><div style="text-align:center">
<strong>Against</strong>
</div></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>1</td>
<td>4</td>
<td>13</td>
</tr>
</tbody>
</table>
<p>Strong consensus against</p>
<p>POLL: For a given scope of applicability (eg translation unit) should
this profile prohibit the use of default initialization leading to no
initialization?</p>
<table>
<thead>
<tr class="header">
<th><div style="text-align:center">
<strong>Favor</strong>
</div></th>
<th><div style="text-align:center">
<strong>Neutral</strong>
</div></th>
<th><div style="text-align:center">
<strong>Against</strong>
</div></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>17</td>
<td>0</td>
<td>0</td>
</tr>
</tbody>
</table>
<p>Unanimous</p>
<h1 data-number="13" id="straw-polls-to-consider"><span class="header-section-number">13</span> Straw Polls To Consider<a href="#straw-polls-to-consider" 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 the profile rely on an attribute on parameters that
indicates what the function is responsible for initializing?</p>
<p>Q4: Should the profile prohibit reinitialization in the constructor
body?</p>
<p>Q5: What should be the mechanism to interact between the verified
world and the unverified world?</p>
<p>Q6: Should we allow to pass verified variables by non-const reference
or pointer to unverified functions? This would make the profile more
useful, but offers lower guarantees.</p>
<h1 data-number="14" id="revision-history"><span class="header-section-number">14</span> Revision History<a href="#revision-history" class="self-link"></a></h1>
<p>R2: 2025-01-13 Initialization at large, for Hadenberg</p>
<p>R1: 2024-10-11 Class initialization, presented in Wrocław</p>
<p>R0: 2024-09-17 Early draft on class initialization for discussion
with the community</p>
<h1 data-number="15" id="bibliography"><span class="header-section-number">15</span> References<a href="#bibliography" class="self-link"></a></h1>
<div id="refs" class="references csl-bib-body hanging-indent" data-entry-spacing="1" role="doc-bibliography">
<div id="ref-CertCPP" class="csl-entry" role="doc-biblioentry">
[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="doc-biblioentry">
[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-P1179R1" class="csl-entry" role="doc-biblioentry">
[P1179R1] Herb Sutter. 2019-11-22. Lifetime safety: Preventing common
dangling. <a href="https://wg21.link/p1179r1"><div class="csl-block">https://wg21.link/p1179r1</div></a>
</div>
<div id="ref-P2795R5" class="csl-entry" role="doc-biblioentry">
[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-P3081R1" class="csl-entry" role="doc-biblioentry">
[P3081R1] Herb Sutter. 2025-01-06. Core safety profiles for C++26. <a href="https://wg21.link/P3081R1"><div class="csl-block">https://wg21.link/P3081R1</div></a>
</div>
<div id="ref-P3274R0" class="csl-entry" role="doc-biblioentry">
[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>
