<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang xml:lang>
<head>
  <meta charset="utf-8" />
  <meta name="generator" content="mpark/wg21" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
  <meta name="dcterms.date" content="2025-05-16" />
  <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>P3402R3</td>
  </tr>
  <tr>
    <td>Date:</td>
    <td>2025-05-16</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, EWG<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-and-interactions-with-non-verified-code" id="toc-exemptions-and-interactions-with-non-verified-code"><span class="toc-section-number">5</span> Exemptions and Interactions with
Non-Verified Code<span></span></a></li>
<li><a href="#constraints-on-verified-code" id="toc-constraints-on-verified-code"><span class="toc-section-number">6</span> Constraints on Verified
Code<span></span></a>
<ul>
<li><a href="#general-constraints" id="toc-general-constraints"><span class="toc-section-number">6.1</span> General
Constraints<span></span></a></li>
<li><a href="#verified-globals" id="toc-verified-globals"><span class="toc-section-number">6.2</span> Verified
Globals<span></span></a></li>
<li><a href="#verified-classes" id="toc-verified-classes"><span class="toc-section-number">6.3</span> Verified
Classes<span></span></a></li>
<li><a href="#verified-functions" id="toc-verified-functions"><span class="toc-section-number">6.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">6.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">6.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">7</span> Templates<span></span></a></li>
<li><a href="#discussion" id="toc-discussion"><span class="toc-section-number">8</span> Discussion<span></span></a>
<ul>
<li><a href="#alternatives-to-profile-suppression-annotation" id="toc-alternatives-to-profile-suppression-annotation"><span class="toc-section-number">8.1</span> Alternatives to Profile
Suppression Annotation<span></span></a></li>
<li><a href="#non-constructor-delegation" id="toc-non-constructor-delegation"><span class="toc-section-number">8.2</span> Non-Constructor
Delegation<span></span></a></li>
<li><a href="#divergences-from-p3274r0" id="toc-divergences-from-p3274r0"><span class="toc-section-number">8.3</span> Divergences from <span class="citation" data-cites="P3274R0">[<span>P3274R0</span>]</span><span></span></a></li>
<li><a href="#overlap-with-p3081r2" id="toc-overlap-with-p3081r2"><span class="toc-section-number">8.4</span> Overlap with <span class="citation" data-cites="P3081R2">[<span>P3081R2</span>]</span><span></span></a></li>
<li><a href="#overlap-with-p1179r1" id="toc-overlap-with-p1179r1"><span class="toc-section-number">8.5</span> Overlap with <span class="citation" data-cites="P1179R1">[<span>P1179R1</span>]</span><span></span></a></li>
<li><a href="#inconsistency-between-declarations-and-implementations" id="toc-inconsistency-between-declarations-and-implementations"><span class="toc-section-number">8.6</span> Inconsistency Between Declarations
and Implementations<span></span></a></li>
</ul></li>
<li><a href="#wording" id="toc-wording"><span class="toc-section-number">9</span> Wording<span></span></a></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="#acknowledgements" id="toc-acknowledgements"><span class="toc-section-number">12</span>
Acknowledgements<span></span></a></li>
<li><a href="#straw-polls-concluded" id="toc-straw-polls-concluded"><span class="toc-section-number">13</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">14</span> Straw Polls To
Consider<span></span></a></li>
<li><a href="#revision-history" id="toc-revision-history"><span class="toc-section-number">15</span> Revision
History<span></span></a></li>
<li><a href="#bibliography" id="toc-bibliography"><span class="toc-section-number">16</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 the <code class="sourceCode cpp">std<span class="op">::</span>initialization</code>
safety profile. Once enforced, this profile 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 via an attribute.</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 an
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
translation unit 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="P3081R2">[<a href="https://isocpp.org/files/papers/P3081R2.pdf" role="doc-biblioref">P3081R2</a>]</span>, <span class="citation" data-cites="P3589R1">[<a href="#ref-P3589R1" role="doc-biblioref">P3589R1</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>
<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 uninitialized
memory (Rule EXP53-CPP). While they imply complete initialization, they
do not specify how to achieve that objective.</p>
<p>However, the automobile safety industry is a bit more specific. For
instance, 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>, 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 accessible”</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 dangling pointers or references (i.e. the <code class="sourceCode cpp">std<span class="op">::</span>lifetime</code>
profile is enforced).</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 enforced).</li>
<li>The programmer uses the exemption mechanisms in a manner that’s
memory-safe.</li>
<li>The program is well-formed.</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 are needed</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>
<li>No cascading effect: a construct being profile-rejected should not
affect other program constructs.</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 overrun problem.</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
(sec <span>6.7.6.2
<a href="https://wg21.link/basic.stc.static">[basic.stc.static]</a></span>)
or thread storage duration (sec <span>6.7.6.3
<a href="https://wg21.link/basic.stc.thread">[basic.stc.thread]</a></span>)
on which the profile is enforced.</p>
<p>A <em>verified class</em> is a class that on which the profile is
enforced.</p>
<p>A <em>verified function</em> is a function on which the profile is
enforced. 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>An <em>object parameter</em> is either the
<code class="sourceCode cpp"><span class="kw">this</span></code> pointer
or an explicit object parameter (sec <span>9.3.4.6
<a href="https://wg21.link/dcl.fct">[dcl.fct]</a></span>).</p>
<p>A <em>verified variable</em> is any of the following * verified
globals * verified data member * variable with automatic storage
duration in a verified function. This includes object parameters of
verified functions. * formal parameter of a verified function</p>
<p><em>Non-verified code</em> is code for which the <code class="sourceCode cpp">std<span class="op">::</span>initialization</code>
profile is not enforced.</p>
<p><em>Acceptable inputs</em> are:</p>
<ol type="1">
<li>The non-exempt transitive closure of reachable verified
variables</li>
<li>The result applying the pointer dereference
(<code class="sourceCode cpp"><span class="op">*</span></code>),
address-of
(<code class="sourceCode cpp"><span class="op">&amp;</span></code>)
built-in operators, or an implicit conversion to boolean, on the symbols
obtained from 1.</li>
<li>Manifestly constant-evaluated expressions (sec <span>7.7
<a href="https://wg21.link/expr.const">[expr.const]</a></span>)</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>
</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
(<code class="sourceCode cpp"><span class="op">.</span></code>) and
arrow
(<code class="sourceCode cpp"><span class="op">-&gt;</span></code>)
operators, except for symbols exempt from verification.</p>
<p>For instance:</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> S <span class="op">{</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> b;</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>  OtherStruct<span class="op">*</span> c;</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> <span class="op">*</span> exempted <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="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> <span class="op">*</span> non_exempted;</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>  OtherStruct exempted_struct <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="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> verified_function<span class="op">(</span>S <span class="op">&amp;</span>s<span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-10"><a href="#cb1-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="cb1-11"><a href="#cb1-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="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>  <span class="kw">auto</span> c <span class="op">=</span> s<span class="op">.</span>c<span class="op">-&gt;</span>c2<span class="op">()</span>;                         <span class="co">//acceptable if c2 is a verified function</span></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a>  <span class="kw">auto</span> d <span class="op">=</span> s<span class="op">.</span>exempted;                      <span class="co">//not acceptable</span></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a>  <span class="kw">auto</span> e <span class="op">=</span> s<span class="op">.</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="cb1-15"><a href="#cb1-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 class="op">{</span></span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> f <span class="op">=</span> s<span class="op">.</span>non_exempted<span class="op">[</span><span class="dv">32</span><span class="op">]</span>;              <span class="co">//acceptable</span></span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a>  <span class="kw">auto</span> g <span class="op">=</span> <span class="op">*</span>s<span class="op">.</span>non_exempted;                   <span class="co">//acceptable</span></span>
<span id="cb1-19"><a href="#cb1-19" 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">//acceptable</span></span>
<span id="cb1-20"><a href="#cb1-20" 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="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a>  <span class="kw">auto</span> j <span class="op">=</span> <span class="op">*</span>s<span class="op">.</span>c;                      <span class="co">//acceptable</span></span>
<span id="cb1-22"><a href="#cb1-22" aria-hidden="true" tabindex="-1"></a>  <span class="dt">bool</span> k <span class="op">=</span> s<span class="op">.</span>b;                                    <span class="co">//acceptable</span></span>
<span id="cb1-23"><a href="#cb1-23" aria-hidden="true" tabindex="-1"></a>  <span class="kw">auto</span> l <span class="op">=</span> <span class="op">&amp;(</span>s<span class="op">.</span>c<span class="op">-&gt;</span>c1<span class="op">)</span>;                      <span class="co">//acceptable</span></span>
<span id="cb1-24"><a href="#cb1-24" aria-hidden="true" tabindex="-1"></a>  <span class="kw">auto</span> local_exempt <span class="op">[[</span><span class="at">indeterminate</span><span class="op">]]</span> <span class="op">=</span> s<span class="op">.</span>b;  <span class="co">//not acceptable</span></span>
<span id="cb1-25"><a href="#cb1-25" aria-hidden="true" tabindex="-1"></a>  <span class="kw">auto</span> m <span class="op">=</span> local_exempt;                      <span class="co">//not acceptable</span></span>
<span id="cb1-26"><a href="#cb1-26" aria-hidden="true" tabindex="-1"></a>  <span class="kw">auto</span> n <span class="op">=</span> <span class="op">*(</span>s<span class="op">.</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="cb1-27"><a href="#cb1-27" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<h1 data-number="5" id="exemptions-and-interactions-with-non-verified-code"><span class="header-section-number">5</span> Exemptions and Interactions with
Non-Verified Code<a href="#exemptions-and-interactions-with-non-verified-code" class="self-link"></a></h1>
<p>Developers can 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> or <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>
attribute from <span class="citation" data-cites="P3081R2">[<a href="https://isocpp.org/files/papers/P3081R2.pdf" role="doc-biblioref">P3081R2</a>]</span>.</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> HighPerformance <span class="op">{</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>    std<span class="op">::</span>byte<span class="op">*</span> buf <span class="op">[[</span><span class="at">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="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> sz <span class="op">=</span> <span class="op">-</span><span class="dv">1</span>;</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">void</span> fill<span class="op">(</span><span class="co">/*...*/</span><span class="op">)</span>;</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> verified_fn<span class="op">(</span><span class="kw">const</span> HighPerformance <span class="op">&amp;</span> hp<span class="op">)</span> <span class="op">{</span></span>
<span id="cb2-8"><a href="#cb2-8" 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 class="op">=</span> hp<span class="op">.</span>buf;</span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>In addition, developers can suppress profile enforcement for code
regions using the <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>
attribute from <span class="citation" data-cites="P3081R2">[<a href="https://isocpp.org/files/papers/P3081R2.pdf" role="doc-biblioref">P3081R2</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="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="cb3-2"><a href="#cb3-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="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> suppress_example<span class="op">(</span><span class="kw">const</span> S <span class="op">*</span>s<span class="op">)</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 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="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> v <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>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>    do_something<span class="op">(</span>v<span class="op">)</span>;</span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Note that verified code can call non-verified functions, with some
limitations. There are no limitations on non-verified code using
verified code.</p>
<h1 data-number="6" id="constraints-on-verified-code"><span class="header-section-number">6</span> Constraints on Verified Code<a href="#constraints-on-verified-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 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="P3081R2">[<a href="https://isocpp.org/files/papers/P3081R2.pdf" role="doc-biblioref">P3081R2</a>]</span>).</li>
<li>Program constructs subject to being profile-rejected that are not
potentially-evaluated (sec <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="6.1" id="general-constraints"><span class="header-section-number">6.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 (sec <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 (sec <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 default initialization or
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 trivial and verified classes, or
pointers or references or arrays thereof.</li>
</ul>
<p>Examples:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> pod <span class="op">{</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> i;</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> j;</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> DefaultDoesNotInitialize <span class="op">{</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>  pod p;</span>
<span id="cb4-7"><a href="#cb4-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="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a>pod podFactory<span class="op">()</span> <span class="op">{</span></span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a>  pod p;    <span class="co">// profile-rejected: general.always.init</span></span>
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> p;</span>
<span id="cb4-13"><a href="#cb4-13" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb4-14"><a href="#cb4-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-15"><a href="#cb4-15" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> InitsWithNonVerified <span class="op">{</span></span>
<span id="cb4-16"><a href="#cb4-16" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> _i;</span>
<span id="cb4-17"><a href="#cb4-17" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> _j;</span>
<span id="cb4-18"><a href="#cb4-18" 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="cb4-19"><a href="#cb4-19" aria-hidden="true" tabindex="-1"></a>  <span class="op">{}</span></span>
<span id="cb4-20"><a href="#cb4-20" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb4-21"><a href="#cb4-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-22"><a href="#cb4-22" 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="cb4-23"><a href="#cb4-23" 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="cb4-24"><a href="#cb4-24" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb4-25"><a href="#cb4-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-26"><a href="#cb4-26" 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> NonVerifiedClass <span class="op">{</span> <span class="co">/**/</span> <span class="op">}</span>;</span>
<span id="cb4-27"><a href="#cb4-27" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-28"><a href="#cb4-28" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> non_verified_in<span class="op">(</span><span class="kw">const</span> NonVerifiedClass <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="cb4-29"><a href="#cb4-29" aria-hidden="true" tabindex="-1"></a>  <span class="co">//...</span></span>
<span id="cb4-30"><a href="#cb4-30" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb4-31"><a href="#cb4-31" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-32"><a href="#cb4-32" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> parent1 <span class="op">{</span></span>
<span id="cb4-33"><a href="#cb4-33" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> i;</span>
<span id="cb4-34"><a href="#cb4-34" 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: general.always.init</span></span>
<span id="cb4-35"><a href="#cb4-35" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb4-36"><a href="#cb4-36" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> child1 <span class="op">:</span> <span class="kw">public</span> parent1 <span class="op">{</span></span>
<span id="cb4-37"><a href="#cb4-37" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> j;</span>
<span id="cb4-38"><a href="#cb4-38" 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="cb4-39"><a href="#cb4-39" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<h2 data-number="6.2" id="verified-globals"><span class="header-section-number">6.2</span> Verified Globals<a href="#verified-globals" class="self-link"></a></h2>
<p>Variables with either static storage duration (sec <span>6.7.6.2
<a href="https://wg21.link/basic.stc.static">[basic.stc.static]</a></span>
- including static data members (sec <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 (sec <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 (sec
<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 (sec
<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 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="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> GetsCorrupted <span class="op">{</span></span>
<span id="cb5-2"><a href="#cb5-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="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> thefield;</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>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> Wrapper <span class="op">{</span></span>
<span id="cb5-7"><a href="#cb5-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="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">static</span> GetsCorrupted wrapped;</span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-11"><a href="#cb5-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="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a>GetsCorrupted corruptingFactory<span class="op">()</span> <span class="op">{</span></span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true" tabindex="-1"></a>    GetsCorrupted ret<span class="op">{}</span>;  <span class="co">//All initialized, good</span></span>
<span id="cb5-14"><a href="#cb5-14" aria-hidden="true" tabindex="-1"></a>    ret<span class="op">.</span>thefield <span class="op">=</span> non_verified_fn<span class="op">()</span>; <span class="co">//Now, some uninitialized memory snuck in</span></span>
<span id="cb5-15"><a href="#cb5-15" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> ret;</span>
<span id="cb5-16"><a href="#cb5-16" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb5-17"><a href="#cb5-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="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">extern</span> <span class="dt">int</span> externInt;</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> readsExtern<span class="op">()</span> <span class="op">{</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> externInt; <span class="co">//compliant</span></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 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 verified globals, 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="6.3" id="verified-classes"><span class="header-section-number">6.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>
<li><code class="sourceCode cpp">derived<span class="op">.</span>are<span class="op">.</span>verified</code>
All derived classes of verified classes must be verified classes.</li>
</ul>
<p>Examples:</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="co">//Not a verified class, but would be compliant if it were</span></span>
<span id="cb7-2"><a href="#cb7-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> NonVerifiedBaseClass <span class="op">{</span></span>
<span id="cb7-3"><a href="#cb7-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="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>  NonVerifiedBaseClass<span class="op">()</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> VerifiedDerivedClass <span class="op">:</span> <span class="kw">public</span> NonVerifiedBaseClass <span class="op">{</span></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> j;</span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a>  VerifiedDerivedClass<span class="op">()</span> <span class="op">:</span> NonVerifiedBaseClass<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="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-11"><a href="#cb7-11" 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>  NonVerifiedDerivedClass <span class="op">:</span> <span class="kw">public</span> VerifiedDerivedClass <span class="op">{</span></span>
<span id="cb7-12"><a href="#cb7-12" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> k;</span>
<span id="cb7-13"><a href="#cb7-13" aria-hidden="true" tabindex="-1"></a>  NonVerifiedDerivedClass<span class="op">()</span> <span class="op">:</span> VerifiedDerivedClass<span class="op">()</span>, k<span class="op">(</span><span class="dv">42</span><span class="op">)</span> <span class="op">{}</span> <span class="co">//profile-rejected: derived.are.verified</span></span>
<span id="cb7-14"><a href="#cb7-14" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
<h2 data-number="6.4" id="verified-functions"><span class="header-section-number">6.4</span> Verified Functions<a href="#verified-functions" class="self-link"></a></h2>
<h3 data-number="6.4.1" id="for-all-verified-functions"><span class="header-section-number">6.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</p>
<ul>
<li>a reference or a pointer to a local variable</li>
<li>lambdas defined in the function</li>
<li>local variables of any <code class="sourceCode cpp">std<span class="op">::</span>function</code>
template instantiation</li>
</ul></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,
<code class="sourceCode cpp"><span class="kw">const</span></code>
reference,
<code class="sourceCode cpp"><span class="kw">const</span></code>
pointer.</li>
</ul></li>
<li><p><code class="sourceCode cpp">verified<span class="op">.</span>overrides</code>
When a member function
<code class="sourceCode cpp"><span class="kw">override</span></code>s a
<code class="sourceCode cpp"><span class="kw">virtual</span></code>
verified function, the overriding function must also be a verified
function.</p></li>
</ul>
<p>Examples:</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="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="cb8-2"><a href="#cb8-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="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-5"><a href="#cb8-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="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> tmp <span class="op">=</span> <span class="dv">0</span>;</span>
<span id="cb8-7"><a href="#cb8-7" 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 class="op">{</span></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a>      tmp <span class="op">=</span> non_verified_function<span class="op">()</span>; <span class="co">//Compliant</span></span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> i <span class="op">*</span> tmp;</span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-13"><a href="#cb8-13" 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="cb8-14"><a href="#cb8-14" 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="cb8-15"><a href="#cb8-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-16"><a href="#cb8-16" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> CallsNonVerifiedWithReference <span class="op">{</span></span>
<span id="cb8-17"><a href="#cb8-17" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> _i;</span>
<span id="cb8-18"><a href="#cb8-18" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> _j;</span>
<span id="cb8-19"><a href="#cb8-19" 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="cb8-20"><a href="#cb8-20" 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="cb8-21"><a href="#cb8-21" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb8-22"><a href="#cb8-22" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb8-23"><a href="#cb8-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-24"><a href="#cb8-24" 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> NonVerifiedBase <span class="op">{</span></span>
<span id="cb8-25"><a href="#cb8-25" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span><span class="op">:</span></span>
<span id="cb8-26"><a href="#cb8-26" aria-hidden="true" tabindex="-1"></a>    NonVerifiedBase<span class="op">()</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb8-27"><a href="#cb8-27" aria-hidden="true" tabindex="-1"></a><span class="kw">protected</span><span class="op">:</span></span>
<span id="cb8-28"><a href="#cb8-28" aria-hidden="true" tabindex="-1"></a>    <span class="kw">virtual</span> <span class="dt">void</span> <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">initialization</span><span class="op">)]]</span> verified_protected_fn<span class="op">()</span>;</span>
<span id="cb8-29"><a href="#cb8-29" aria-hidden="true" tabindex="-1"></a><span class="kw">private</span><span class="op">:</span></span>
<span id="cb8-30"><a href="#cb8-30" aria-hidden="true" tabindex="-1"></a>  <span class="co">// ...</span></span>
<span id="cb8-31"><a href="#cb8-31" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb8-32"><a href="#cb8-32" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-33"><a href="#cb8-33" 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> NonVerifiedDerived <span class="op">:</span></span>
<span id="cb8-34"><a href="#cb8-34" aria-hidden="true" tabindex="-1"></a>  <span class="kw">public</span> NonVerifiedBase <span class="op">{</span></span>
<span id="cb8-35"><a href="#cb8-35" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span><span class="op">:</span></span>
<span id="cb8-36"><a href="#cb8-36" aria-hidden="true" tabindex="-1"></a>  NonVerifiedDerived<span class="op">()</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb8-37"><a href="#cb8-37" aria-hidden="true" tabindex="-1"></a><span class="kw">protected</span><span class="op">:</span></span>
<span id="cb8-38"><a href="#cb8-38" aria-hidden="true" tabindex="-1"></a>    <span class="dt">void</span> verified_protected_fn<span class="op">()</span> <span class="kw">override</span>; <span class="co">//profile-rejected: verified.overrides</span></span>
<span id="cb8-39"><a href="#cb8-39" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb8-40"><a href="#cb8-40" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-41"><a href="#cb8-41" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> VerifiedBase <span class="op">{</span></span>
<span id="cb8-42"><a href="#cb8-42" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span><span class="op">:</span></span>
<span id="cb8-43"><a href="#cb8-43" aria-hidden="true" tabindex="-1"></a>    VerifiedBase<span class="op">()</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb8-44"><a href="#cb8-44" aria-hidden="true" tabindex="-1"></a><span class="kw">protected</span><span class="op">:</span></span>
<span id="cb8-45"><a href="#cb8-45" aria-hidden="true" tabindex="-1"></a>    <span class="kw">virtual</span> <span class="dt">void</span> verified_protected_fn<span class="op">()</span>;</span>
<span id="cb8-46"><a href="#cb8-46" aria-hidden="true" tabindex="-1"></a><span class="kw">private</span><span class="op">:</span></span>
<span id="cb8-47"><a href="#cb8-47" aria-hidden="true" tabindex="-1"></a>  <span class="co">// ...</span></span>
<span id="cb8-48"><a href="#cb8-48" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb8-49"><a href="#cb8-49" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-50"><a href="#cb8-50" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> VerifiedDerived <span class="op">:</span> <span class="kw">public</span> VerifiedBase <span class="op">{</span></span>
<span id="cb8-51"><a href="#cb8-51" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span><span class="op">:</span></span>
<span id="cb8-52"><a href="#cb8-52" aria-hidden="true" tabindex="-1"></a>    VerifiedDerived<span class="op">()</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb8-53"><a href="#cb8-53" aria-hidden="true" tabindex="-1"></a><span class="kw">protected</span><span class="op">:</span></span>
<span id="cb8-54"><a href="#cb8-54" aria-hidden="true" tabindex="-1"></a>    <span class="dt">void</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> verified_protected_fn<span class="op">()</span> <span class="kw">override</span>; <span class="co">//profile-rejected: verified.overrides</span></span>
<span id="cb8-55"><a href="#cb8-55" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb8-56"><a href="#cb8-56" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-57"><a href="#cb8-57" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> unsafeRetLambda<span class="op">(</span><span class="dt">int</span> i<span class="op">){</span> <span class="co">//passed by copy</span></span>
<span id="cb8-58"><a href="#cb8-58" aria-hidden="true" tabindex="-1"></a>  <span class="kw">auto</span> lambda <span class="op">=</span> <span class="op">[&amp;</span>i<span class="op">]()</span> <span class="op">{</span> <span class="co">// reference to local variable</span></span>
<span id="cb8-59"><a href="#cb8-59" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> i <span class="op">*</span> i;</span>
<span id="cb8-60"><a href="#cb8-60" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span>;</span>
<span id="cb8-61"><a href="#cb8-61" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> lambda; <span class="co">//profile-rejected: restrict.returns</span></span>
<span id="cb8-62"><a href="#cb8-62" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<h3 data-number="6.4.2" id="for-constructors-of-verified-classes"><span class="header-section-number">6.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> (sec <span>11.9.3
<a href="https://wg21.link/class.base.init">[class.base.init]</a></span>)
to initialize them.</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> (sec
<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 omission 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 (sec <span>7.6.19
<a href="https://wg21.link/expr.ass">[expr.ass]</a></span>).</li>
</ul>
<h4 data-number="6.4.2.1" id="compliant-examples"><span class="header-section-number">6.4.2.1</span> Compliant Examples<a href="#compliant-examples" class="self-link"></a></h4>
<div class="sourceCode" id="cb9"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> ValueInitialized <span class="op">{</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>  pod p<span class="op">{}</span>;</span>
<span id="cb9-3"><a href="#cb9-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="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> InitWithVerifiedReturnValue <span class="op">{</span></span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a>  <span class="kw">static</span> pod podFactory<span class="op">()</span>;</span>
<span id="cb9-8"><a href="#cb9-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="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> WithExemption <span class="op">{</span></span>
<span id="cb9-12"><a href="#cb9-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="cb9-13"><a href="#cb9-13" aria-hidden="true" tabindex="-1"></a>  <span class="dt">size_t</span>    buf_size;</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>  WithExemption<span class="op">()</span> <span class="op">:</span> buf_size<span class="op">(</span><span class="dv">0</span><span class="op">)</span>, i<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="cb9-16"><a href="#cb9-16" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb9-17"><a href="#cb9-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-18"><a href="#cb9-18" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> SafeDefaultInit <span class="op">{</span></span>
<span id="cb9-19"><a href="#cb9-19" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> i;</span>
<span id="cb9-20"><a href="#cb9-20" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> j;</span>
<span id="cb9-21"><a href="#cb9-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="cb9-22"><a href="#cb9-22" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb9-23"><a href="#cb9-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-24"><a href="#cb9-24" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> ReliesOnDefaultInit <span class="op">{</span></span>
<span id="cb9-25"><a href="#cb9-25" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> i;</span>
<span id="cb9-26"><a href="#cb9-26" aria-hidden="true" tabindex="-1"></a>  SafeDefaultInit sdi;</span>
<span id="cb9-27"><a href="#cb9-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="cb9-28"><a href="#cb9-28" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb9-29"><a href="#cb9-29" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-30"><a href="#cb9-30" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> MixedInits <span class="op">{</span></span>
<span id="cb9-31"><a href="#cb9-31" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> i;</span>
<span id="cb9-32"><a href="#cb9-32" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> j;</span>
<span id="cb9-33"><a href="#cb9-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="cb9-34"><a href="#cb9-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="cb9-35"><a href="#cb9-35" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb9-36"><a href="#cb9-36" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-37"><a href="#cb9-37" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> WithCallInCtorBody <span class="op">{</span></span>
<span id="cb9-38"><a href="#cb9-38" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> i;</span>
<span id="cb9-39"><a href="#cb9-39" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> j;</span>
<span id="cb9-40"><a href="#cb9-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="cb9-41"><a href="#cb9-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="cb9-42"><a href="#cb9-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="cb9-43"><a href="#cb9-43" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb9-44"><a href="#cb9-44" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb9-45"><a href="#cb9-45" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-46"><a href="#cb9-46" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> UpdatesGlobal <span class="op">{</span></span>
<span id="cb9-47"><a href="#cb9-47" aria-hidden="true" tabindex="-1"></a>  <span class="kw">static</span> <span class="dt">unsigned</span> num_allocations;</span>
<span id="cb9-48"><a href="#cb9-48" aria-hidden="true" tabindex="-1"></a>  UpdatesGlobal<span class="op">()</span> <span class="op">{</span></span>
<span id="cb9-49"><a href="#cb9-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="cb9-50"><a href="#cb9-50" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb9-51"><a href="#cb9-51" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb9-52"><a href="#cb9-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="cb9-53"><a href="#cb9-53" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-54"><a href="#cb9-54" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> CallsVerifiedNonConst <span class="op">{</span></span>
<span id="cb9-55"><a href="#cb9-55" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> i;</span>
<span id="cb9-56"><a href="#cb9-56" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> j;</span>
<span id="cb9-57"><a href="#cb9-57" aria-hidden="true" tabindex="-1"></a>  <span class="dt">void</span> mutating<span class="op">()</span>;</span>
<span id="cb9-58"><a href="#cb9-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="cb9-59"><a href="#cb9-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="cb9-60"><a href="#cb9-60" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb9-61"><a href="#cb9-61" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
<h4 data-number="6.4.2.2" id="profile-rejected-examples"><span class="header-section-number">6.4.2.2</span> Profile-Rejected Examples<a href="#profile-rejected-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> WrongOrder <span class="op">{</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> i;</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> j;</span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>  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="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> MissingInit <span class="op">{</span></span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> i;</span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true" tabindex="-1"></a>  MissingInit<span class="op">()</span> <span class="op">{}</span> <span class="co">//profile-rejected: init.all</span></span>
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb10-11"><a href="#cb10-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-12"><a href="#cb10-12" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> InitInCtorBody <span class="op">{</span></span>
<span id="cb10-13"><a href="#cb10-13" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> i;</span>
<span id="cb10-14"><a href="#cb10-14" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> j;</span>
<span id="cb10-15"><a href="#cb10-15" 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-16"><a href="#cb10-16" aria-hidden="true" tabindex="-1"></a>  InitInCtorBody<span class="op">()</span> <span class="op">{</span></span>
<span id="cb10-17"><a href="#cb10-17" aria-hidden="true" tabindex="-1"></a>      i <span class="op">=</span> <span class="dv">123</span>;</span>
<span id="cb10-18"><a href="#cb10-18" aria-hidden="true" tabindex="-1"></a>      j <span class="op">=</span> <span class="dv">456</span>;</span>
<span id="cb10-19"><a href="#cb10-19" aria-hidden="true" tabindex="-1"></a>      <span class="co">//profile-rejected: init.list</span></span>
<span id="cb10-20"><a href="#cb10-20" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb10-21"><a href="#cb10-21" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb10-22"><a href="#cb10-22" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-23"><a href="#cb10-23" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> CallsNonVerifiedWithFieldReference <span class="op">{</span></span>
<span id="cb10-24"><a href="#cb10-24" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> _i;</span>
<span id="cb10-25"><a href="#cb10-25" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> _j;</span>
<span id="cb10-26"><a href="#cb10-26" 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="cb10-27"><a href="#cb10-27" 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="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 class="op">}</span>;</span></code></pre></div>
<h1 data-number="7" id="templates"><span class="header-section-number">7</span> Templates<a href="#templates" class="self-link"></a></h1>
<p>In the case of templated classes, the property is verified during
template instantiation.</p>
<div class="sourceCode" id="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">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="cb11-2"><a href="#cb11-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="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-4"><a href="#cb11-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="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Template <span class="op">{</span></span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a>  T field <span class="op">=</span> T<span class="op">()</span>;</span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb11-8"><a href="#cb11-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-9"><a href="#cb11-9" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> uses_template<span class="op">()</span> <span class="op">{</span></span>
<span id="cb11-10"><a href="#cb11-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: general.type</span></span>
<span id="cb11-11"><a href="#cb11-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="cb11-12"><a href="#cb11-12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<h1 data-number="8" id="discussion"><span class="header-section-number">8</span> Discussion<a href="#discussion" class="self-link"></a></h1>
<h2 data-number="8.1" id="alternatives-to-profile-suppression-annotation"><span class="header-section-number">8.1</span> Alternatives to Profile
Suppression Annotation<a href="#alternatives-to-profile-suppression-annotation" class="self-link"></a></h2>
<p>An earlier version of this paper proposed <code class="sourceCode cpp">std<span class="op">::</span>verified_cast</code>
as a terser alternative to block-level disablement and included it in
the profile specification. This function would allow programmers to use
return values from non-verified functions in initialization lists in a
way that’s more natural than profile disablement. It would be the C++
equivalent of Rust’s <code class="sourceCode cpp">unsafe</code>
expression.</p>
<p>However, it would be desirable to add a template parameter allowing
programmers to specify which profile(s) are suppressed (e.g. <code class="sourceCode cpp">std<span class="op">::</span>verified_cast<span class="op">&lt;</span>std<span class="op">::</span>initialization<span class="op">&gt;</span></code>),
and allow for a full equivalency to Rust’s
<code class="sourceCode cpp">unsafe</code> expression with <code class="sourceCode cpp">std<span class="op">::</span>verified_cast<span class="op">&lt;</span>std<span class="op">::</span>all<span class="op">&gt;</span></code>.
However, what exactly should be the template type of <code class="sourceCode cpp">std<span class="op">::</span>verified_cast<span class="op">&lt;&gt;</span></code>?
<code class="sourceCode cpp">std<span class="op">:</span>all</code> and
<code class="sourceCode cpp">std<span class="op">::</span>initialization</code>
are not types, but strings that a compiler would recognize in a profile
attribute. Allowing <code class="sourceCode cpp">std<span class="op">::</span>verified_cast<span class="op">&lt;&gt;</span></code>
would thus require language-level changes, or the definition of types in
the standard library that have little meaning outside of safety
profiles. Both options are likely to reduce consensus.</p>
<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">class</span> ForVCast <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> k;</span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>  ForVCast<span class="op">():</span> i<span class="op">(</span>std<span class="op">::</span>verified_cast<span class="op">&lt;</span>std<span class="op">::</span>initialization<span class="op">&gt;(</span>non_verified<span class="op">()))</span>,</span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a>              j<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> non_verified<span class="op">()</span> <span class="op">}</span> <span class="op">)</span>, <span class="co">//doesn&#39;t compile</span></span>
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true" tabindex="-1"></a>              k<span class="op">([]()</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> <span class="op">{</span> <span class="cf">return</span> non_verified<span class="op">()</span>; <span class="op">}())</span></span>
<span id="cb12-8"><a href="#cb12-8" aria-hidden="true" tabindex="-1"></a>              <span class="op">{}</span></span>
<span id="cb12-9"><a href="#cb12-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>During the Hagenberg meeting, SG23 attendees brought up the
similarities between <code class="sourceCode cpp">std<span class="op">::</span>verified_cast</code>
and
<code class="sourceCode cpp">std<span class="op">::</span>launder</code>.
We, consider that
<code class="sourceCode cpp">std<span class="op">::</span>launder</code>
is not a good way to suppress profile enforcement, as this would embue
existing code with additional properties that its authors did not
anticipate.</p>
<p>This proposal is ultimately orthogonal to the profile specification
and, given the technical constraints, we would pursue it in a separate
paper going forward.</p>
<h2 data-number="8.2" id="non-constructor-delegation"><span class="header-section-number">8.2</span> Non-Constructor Delegation<a href="#non-constructor-delegation" 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="cb13"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb13-1"><a href="#cb13-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="cb13-2"><a href="#cb13-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="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>  <span class="co">//...</span></span>
<span id="cb13-5"><a href="#cb13-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="cb13-6"><a href="#cb13-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="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> DelegatingInit <span class="op">{</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> member;</span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>  DelegatingInit<span class="op">()</span> <span class="op">{</span></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>    internal_init<span class="op">(&amp;</span>member<span class="op">)</span>;</span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a>  <span class="dt">void</span> 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="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>The latter 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="8.3" id="divergences-from-p3274r0"><span class="header-section-number">8.3</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="8.4" id="overlap-with-p3081r2"><span class="header-section-number">8.4</span> Overlap with <span class="citation" data-cites="P3081R2">[<a href="https://isocpp.org/files/papers/P3081R2.pdf" role="doc-biblioref">P3081R2</a>]</span><a href="#overlap-with-p3081r2" class="self-link"></a></h2>
<p>The rule for Type.6 proposed by <span class="citation" data-cites="P3081R2">[<a href="https://isocpp.org/files/papers/P3081R2.pdf" role="doc-biblioref">P3081R2</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="P3081R2">[<a href="https://isocpp.org/files/papers/P3081R2.pdf" role="doc-biblioref">P3081R2</a>]</span> is foundational to this paper,
we encourage <span class="citation" data-cites="P3081R2">[<a href="https://isocpp.org/files/papers/P3081R2.pdf" role="doc-biblioref">P3081R2</a>]</span> to specify an initialization
profile containing only rule Type.6, which this paper would eventually
build upon.</p>
<h2 data-number="8.5" id="overlap-with-p1179r1"><span class="header-section-number">8.5</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">std<span class="op">::</span>lifetime</code>
profile to some extent (<span class="citation" data-cites="P1179R1">[<a href="https://wg21.link/p1179r1" role="doc-biblioref">P1179R1</a>]</span>), as it aims to avoid a read of
nondeterminate memory contents by the caller of a verified function.
Thus, the rule leads to profile-rejected safe code, as illustrated
below.</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">auto</span> safeRetLambda<span class="op">(</span><span class="dt">int</span> i<span class="op">){</span> <span class="co">//passed by copy</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">auto</span> lambda <span class="op">=</span> <span class="op">[</span>i<span class="op">]()</span> <span class="op">{</span> <span class="co">// copy of local variable</span></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> i <span class="op">*</span> i;</span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span>;</span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> lambda; <span class="co">//safe, but profile-rejected: restrict.returns</span></span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>It would be desirable to ensure that only function objects capturing
local variables be prohibited. But that seems difficult to do so without
dataflow analysis. In the example below, only
<code class="sourceCode cpp">lambda1</code> would be unsafe.</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>std<span class="op">::</span>function<span class="op">&lt;</span><span class="dt">int</span><span class="op">()&gt;</span> unsafeStdFunction<span class="op">(</span><span class="dt">int</span> i<span class="op">){</span> <span class="co">//passed by copy</span></span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>  std<span class="op">::</span>function<span class="op">&lt;</span><span class="dt">int</span><span class="op">()&gt;</span> lambda1 <span class="op">=</span> <span class="op">[&amp;</span>i<span class="op">]()</span> <span class="op">{</span> <span class="co">// reference to local variable</span></span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> i <span class="op">*</span> i;</span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span>;</span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a>  std<span class="op">::</span>function<span class="op">&lt;</span><span class="dt">int</span><span class="op">()&gt;</span> lambda2 <span class="op">=</span> <span class="op">[</span>i<span class="op">]()</span> <span class="op">{</span> <span class="co">// copy of local variable</span></span>
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> i <span class="op">*</span> i;</span>
<span id="cb16-7"><a href="#cb16-7" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span>;</span>
<span id="cb16-8"><a href="#cb16-8" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> nondet<span class="op">()?</span> lambda1 <span class="op">:</span> lambda2; <span class="co">//profile-rejected: restrict.returns</span></span>
<span id="cb16-9"><a href="#cb16-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>It may be preferable to delegate cases like these to the <code class="sourceCode cpp">std<span class="op">::</span>lifetime</code>
profile and rewrite the rule 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="8.6" id="inconsistency-between-declarations-and-implementations"><span class="header-section-number">8.6</span> Inconsistency Between
Declarations and Implementations<a href="#inconsistency-between-declarations-and-implementations" class="self-link"></a></h2>
<p>Different translation units may have different profiles enabled. This
could lead to situations where a translation unit mistakenly expects a
symbol to comply with the requirements of this profile. Consider the
example below, whereby the translation unit implementing
<code class="sourceCode cpp">foo</code> does so without the
initialization profile. However, another translation unit requires the
initialization profile, and depends on
<code class="sourceCode cpp">foo</code>.</p>
<div class="sourceCode" id="cb17"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="co">//in impl.cpp</span></span>
<span id="cb17-2"><a href="#cb17-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="cb17-3"><a href="#cb17-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="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a><span class="co">//in caller.cpp</span></span>
<span id="cb17-6"><a href="#cb17-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="cb17-7"><a href="#cb17-7" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> foo<span class="op">()</span>;</span>
<span id="cb17-8"><a href="#cb17-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-9"><a href="#cb17-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="cb17-10"><a href="#cb17-10" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> foo<span class="op">()</span>;</span>
<span id="cb17-11"><a href="#cb17-11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>This issue was anticipated in part in the wording of <span class="citation" data-cites="P3081R2">[<a href="https://isocpp.org/files/papers/P3081R2.pdf" role="doc-biblioref">P3081R2</a>]</span>, section [dcl.attr.profile]. We
consider that this situation make the program ill-formed, no diagnostic
required (IFNDR). This is line with other attributes in the standard
(sec <span>9.12
<a href="https://wg21.link/dcl.attr">[dcl.attr]</a></span>) and should
be added to the general profile specification.</p>
<h1 data-number="9" id="wording"><span class="header-section-number">9</span> Wording<a href="#wording" class="self-link"></a></h1>
<!--global.static.init-->
<p>We add a paragraph to section <span>6.9.3.2
<a href="https://wg21.link/basic.start.static">[basic.start.static]</a></span>
as follows:</p>
<div class="add" style="color: #006e28">

<ol start="24" type="a">
<li>Whenever the
<code class="sourceCode default">std::initialization</code> profile is
enforced, any dynamic initialization must be performed as static
initialization under the terms of paragraph 3. Otherwise, the statement
is profile-rejected by
<code class="sourceCode default">std::initialization</code>.</li>
</ol>

</div>
<!-- general.verif.init -->
<p>We add a paragraph to section <span>9.4
<a href="https://wg21.link/dcl.init">[dcl.init]</a></span> as
follows:</p>
<div class="add" style="color: #006e28">

<ol start="24" type="a">
<li>Initialization-verified variables, except for function formal
parameters, must either be default-initialized, or be initialized using
only initialization-acceptable inputs. Otherwise, the class declaration
is profile-rejected by
<code class="sourceCode default">std::initialization</code>.</li>
</ol>

</div>
<!--base.are.verified and derived.are.verified -->
<p>We add a paragraph to section <span>11.7.2
<a href="https://wg21.link/class.mi">[class.mi]</a></span> as
follows:</p>
<div class="add" style="color: #006e28">

<ol start="24" type="a">
<li>All base classes of an initialization-verified class are also
initialization- verified classes. Otherwise, the class declaration is
profile-rejected by
<code class="sourceCode default">std::initialization</code>.</li>
<li>Whenever any base classes is an initialization-verified class, the
derived class is also initialization-verified. Otherwise, the class
declaration is profile-rejected by
<code class="sourceCode default">std::initialization</code>.</li>
</ol>

</div>
<!-- verified.overrides -->
<p>We add a paragraph to section <span>11.7.3
<a href="https://wg21.link/class.virtual">[class.virtual]</a></span> as
follows:</p>
<div class="add" style="color: #006e28">

<ol start="24" type="a">
<li>A function overrididing a virtual initialization-verified function
must also be initialization-verified. Otherwise, the function
declaration is profile-rejected by
<code class="sourceCode default">std::initialization</code>.</li>
</ol>

</div>
<!--restrict.returns-->
<p>We add a section to section <span>8.7.4
<a href="https://wg21.link/stmt.return">[stmt.return]</a></span> as
follows:</p>
<div class="add" style="color: #006e28">

<ol start="24" type="a">
<li>The return statement of an initialization-verified function must
return an initialization-acceptable input, except a lambda defined in
the function or any local variable instantiating the
<code class="sourceCode default">std::function</code> template.</li>
</ol>

</div>
<!--no.ref.args-->
<p>We add a paragraph to section <span>7.6.1.3
<a href="https://wg21.link/expr.call">[expr.call]</a></span> as
follows:</p>
<div class="add" style="color: #006e28">

<ol start="24" type="a">
<li>Arguments to function calls which are initialization-acceptable
inputs, within an initialization-verified function, for which call
targets are not initialization-verified must only be passed by copy,
constant reference or constant pointer. Otherwise, the expression is
profile-rejected by the
<code class="sourceCode default">std::initialization</code>
profile.</li>
</ol>

</div>
<!-- init.before.read , init.all, init.list and other things in the standard  -->
<p>We modify section <span>11.9
<a href="https://wg21.link/class.init">[class.init]</a></span> as
follows:</p>
<p><span class="marginalizedparent"><a class="marginalized">16</a></span> Member
functions (including virtual member functions, [class.virtual]) can be
called for an object under construction. Similarly, an object under
construction can be the operand of the typeid operator ([expr.typeid])
or of a dynamic_cast ([expr.dynamic.cast]). However, if these operations
are performed in a ctor-initializer (or in a function called directly or
indirectly from a ctor-initializer) before all the mem-initializers for
base classes have completed, the program has undefined behavior <span class="add" style="color: #006e28"><ins>if the
<span><code class="sourceCode default">std::initialization</code></span>
profile is not enforced. Otherwise, it is profile-rejected by the
<span><code class="sourceCode default">std::initialization</code></span>
profile.</ins></span>.</p>
<div class="add" style="color: #006e28">

<ol start="24" type="a">
<li>Non-delegating constructors that are initialization-verified
functions must initialize all initialization-verified non-static data
members declared in their class in a <em>mem-initializer-list</em>,
except for data members declared with a brace-or-equal-initializer (sec
11.4.1 <span>11.4.1
<a href="https://wg21.link/class.mem.general">[class.mem.general]</a></span>)
and data members of a type with a default constructor and its omission
from the <em>mem-initializer-list</em> would result in the use of that
default constructor. Otherwise, the constructor is profile-rejected by
the <code class="sourceCode default">std::initialization</code>
profile.</li>
<li>Non-delegating constructors that are initialization-verified
functions must initialize initialization-verified non-static data
members declared in their class before they are read. Otherwise, the
constructor is profile-rejected by the
<code class="sourceCode default">std::initialization</code>
profile.</li>
</ol>

</div>
<!-- general.verif.init -->
<p>We add a section to <a href="https://wg21.link/expr.assign">[expr.assign]</a> as follows:</p>
<div class="add" style="color: #006e28">

<ol start="24" type="a">
<li>When the left operand of a simple assignment is an
initialization-verified variable, the right operand must be an
initialization-acceptable input.</li>
</ol>

</div>
<p>The following wording changes section assumes that <span class="citation" data-cites="P3081R2">[<a href="https://isocpp.org/files/papers/P3081R2.pdf" role="doc-biblioref">P3081R2</a>]</span> and <span class="citation" data-cites="P3589R1">[<a href="#ref-P3589R1" role="doc-biblioref">P3589R1</a>]</span> are adopted. We propose
insertions into the former’s wording.</p>
<p>We add the following entry to <a href="https://wg21.link/tab:profiles.summary">[tab:profiles.summary]</a>:</p>
<table>
<colgroup>
<col style="width: 32%" />
<col style="width: 67%" />
</colgroup>
<tbody>
<tr class="odd">
<td>profile-name</td>
<td>Subclauses</td>
</tr>
<tr class="even">
<td><span class="add" style="color: #006e28"><ins>initialization</ins></span></td>
<td><span class="add" style="color: #006e28"><ins><span>6.9.3.2
<a href="https://wg21.link/basic.start.static">[basic.start.static]</a></span>,
<span>11.7.2
<a href="https://wg21.link/class.mi">[class.mi]</a></span>,</ins></span>
<span class="add" style="color: #006e28"><ins><span>8.7.4
<a href="https://wg21.link/stmt.return">[stmt.return]</a></span>,
<span>7.6.1.3
<a href="https://wg21.link/expr.call">[expr.call]</a></span>,</ins></span>
<span class="add" style="color: #006e28"><ins><span>11.9
<a href="https://wg21.link/class.init">[class.init]</a></span>,
<span>11.7.3
<a href="https://wg21.link/class.virtual">[class.virtual]</a></span></ins></span></td>
</tr>
</tbody>
</table>
<p>We add a paragraph to section [dcl.attr.profile] as follows:</p>
<div class="add" style="color: #006e28">

<ol start="24" type="a">
<li>Whenever profile enforcement on a program construct C is not
identical between translation units, the program is ill-defined, no
diagnostic required.</li>
</ol>

</div>
<p>We add a section after [dcl.attr.profile] as follows:</p>
<div class="add" style="color: #006e28">

<ol start="24" type="a">
<li>Initialization profile</li>
</ol>
<ol type="1">
<li><p>Whenever the
<code class="sourceCode default">std::initialization</code> profile is
enforced on program construct C , the
<code class="sourceCode default">std::type</code> and
<code class="sourceCode default">std::lifetime</code> profiles are also
enforced on C. Otherwise, the translation unit is profile-rejected by
<code class="sourceCode default">std::initialization</code>.</p></li>
<li><p>Definitions An <em>initialization-verified class</em> is a class
for which the
<code class="sourceCode default">std::initialization</code> profile is
enforced.</p></li>
</ol>
<p>An <em>initialization-verified function</em> is a function for which
the <code class="sourceCode default">std::initialization</code> profile
is enforced. This includes the member functions of
initialization-verified classes, and lambdas defined by
initialization-verified function.</p>
<p>An <em>initialization-verified variable</em> is any of the following,
when the <code class="sourceCode default">std::initialization</code>
profile is enforced:</p>
<ul>
<li>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>)</li>
<li>a non-static data member of a initialization-verified class,</li>
<li>a variable with automatic storage duration in an
initialization-verified function,</li>
<li>an initialization-verified function’s formal parameters.</li>
</ul>
<p>An <em>object parameter</em> is either the
<code class="sourceCode default">this</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>Initialization-acceptable inputs</em> are any of the
following.</p>
<ol type="a">
<li>The non-exempt transitive closure of reachable
initialization-verified variables</li>
<li>The result applying the pointer dereference
(<code class="sourceCode default">*</code>), address-of
(<code class="sourceCode default">&amp;</code>) built-in operators, or
an implicit conversion to boolean, on the symbols obtained from a.</li>
<li>Manifestly constant-evaluated expressions (<span>7.7
<a href="https://wg21.link/expr.const">[expr.const]</a></span>)</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>
</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 only include symbols for which the
<code class="sourceCode default">std::initialization</code> profile is
enforced.</p>
<!--general.type-->
<ol start="3" type="1">
<li>All initialization-verified variables’ type can only be trivial
types and verified classes, pointers thereof, references thereof or
arrays thereof.</li>
</ol>

</div>
<!-- general.always.init handled by type profile -->
<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>We propose the <code class="sourceCode cpp">std<span class="op">::</span>initialization</code>
safety profile. When enforce, it guarantees that all affected code will
initialize both local and global variables to determinate values,
assuming that</p>
<ol type="a">
<li>the data used for construction is itself initialized properly,</li>
<li>the
<code class="sourceCode cpp">std<span class="op">::</span>type</code>
and <code class="sourceCode cpp">std<span class="op">::</span>lifetime</code>
profiles are enforced on verified code and its transitive callees,</li>
<li>the program is well-formed,</li>
<li>code in the regions where the profile maintains the profile’s
properties</li>
</ol>
<p>The profile does not depend on the presence of specific modern C++
features and can thus be applied to legacy code bases. Thus, developers
on legacy code bases that are still using older versions of the C++
standard could take advantage of this profile.</p>
<h1 data-number="12" id="acknowledgements"><span class="header-section-number">12</span> Acknowledgements<a href="#acknowledgements" class="self-link"></a></h1>
<p>The authors would like to thank the attendees of SG23 meeting, as
well as contributors on the SG23 reflector for their valuable input. We
especially want to thank Tom Honermann and Jens Maurer.</p>
<h1 data-number="13" id="straw-polls-concluded"><span class="header-section-number">13</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>
<p>The following straw polls were conducted during the Hagenberg 2025
meeting.</p>
<p>POLL: We support adding <code class="sourceCode cpp">verify_cast<span class="op">&lt;&gt;</span></code>
to allow suppression of the initialization profile for specific
accesses.</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>3</td>
<td>4</td>
<td>0</td>
</tr>
</tbody>
</table>
<p>Consensus in favour</p>
<p>POLL: Should the initialization profile allow re-initialization in
the construction body?</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>7</td>
<td>1</td>
<td>0</td>
</tr>
</tbody>
</table>
<p>Consensus in favor</p>
<p>POLL: Should we allow passing verified data by non-const reference to
unverified functions under this profile?</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>0</td>
<td>2</td>
<td>4</td>
</tr>
</tbody>
</table>
<p>POLL: Should we allow passing verified data by const reference to
unverified functions under this profile?</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>5</td>
<td>2</td>
<td>0</td>
</tr>
</tbody>
</table>
<h1 data-number="14" id="straw-polls-to-consider"><span class="header-section-number">14</span> Straw Polls To Consider<a href="#straw-polls-to-consider" class="self-link"></a></h1>
<p>Q1: SG23 forwards this paper to EWG.</p>
<p>Q2: Should the profile rely on an attribute on parameters that
indicates what the function is responsible for initializing?</p>
<p>Q3: The <code class="sourceCode cpp">std<span class="op">::</span>lifetime</code>
profile should prohibit to identify dangling references after function
return rather than the <code class="sourceCode cpp">std<span class="op">::</span>initialization</code>
profile.</p>
<h1 data-number="15" id="revision-history"><span class="header-section-number">15</span> Revision History<a href="#revision-history" class="self-link"></a></h1>
<p>R3: Update for Sofia</p>
<ul>
<li>Removed the
<code class="sourceCode cpp">no<span class="op">.</span>reassign</code>
rule based on straw poll results.</li>
<li>Reduced <code class="sourceCode cpp">std<span class="op">::</span>verified_cast</code>
to a discussion, taking in consideration straw poll results.</li>
<li>Addressed the discrepancy problem as IFNDR.</li>
<li>Expanded the set of acceptable inputs.</li>
<li>Modified the <code class="sourceCode cpp">restrict<span class="op">.</span>returns</code>
rule.</li>
<li>Updated text to use a trivial type instead of a POD type.</li>
<li>Added wording.</li>
</ul>
<p>R2: 2025-01-13 Initialization at large, for Hagenberg</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="16" id="bibliography"><span class="header-section-number">16</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-P3081R2" class="csl-entry" role="doc-biblioentry">
[P3081R2] Herb Sutter. 2025-02-04. Core safety profiles for C++26. <a href="https://isocpp.org/files/papers/P3081R2.pdf"><div class="csl-block">https://isocpp.org/files/papers/P3081R2.pdf</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 id="ref-P3589R1" class="csl-entry" role="doc-biblioentry">
[P3589R1] Gabriel Dos Reis. 2025-02-02. C++ Profiles: The Framework.
</div>
</div>
</div>
</div>
</body>
</html>
