<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang xml:lang>
<head>
  <meta charset="utf-8" />
  <meta name="generator" content="mpark/wg21" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
  <meta name="dcterms.date" content="2024-11-21" />
  <title>Standard library hardening</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">Standard library
hardening</h1>
<table style="border:none;float:right">
  <tr>
    <td>Document #:</td>
    <td>P3471R1</td>
  </tr>
  <tr>
    <td>Date:</td>
    <td>2024-11-21</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>
      Library Evolution, SG23<br>
    </td>
  </tr>
  <tr>
    <td style="vertical-align:top">Reply-to:</td>
    <td>
      Konstantin Varlamov<br>&lt;<a href="mailto:varconst@apple.com" class="email">varconst@apple.com</a>&gt;<br>
      Louis Dionne<br>&lt;<a href="mailto:ldionne@apple.com" class="email">ldionne@apple.com</a>&gt;<br>
    </td>
  </tr>
</table>
</header>
<div style="clear:both">
<h1 data-number="1" id="introduction"><span class="header-section-number">1</span> Introduction<a href="#introduction" class="self-link"></a></h1>
<p>This paper proposes introducing <em>standard library hardening</em>
into the C++ Standard. Hardening allows turning some instances of
undefined behavior in the standard library into a contract violation.
This proposal is based on our experience implementing <a href="https://libcxx.llvm.org/Hardening.html">hardening in libc++</a>
and deploying it widely.</p>
<h1 data-number="2" id="revision-history"><span class="header-section-number">2</span> Revision history<a href="#revision-history" class="self-link"></a></h1>
<ul>
<li>R0: Initial proposal based on “terminating in an
implementation-defined way”</li>
<li>R1: Revision rebased on top of contract violations</li>
</ul>
<h1 data-number="3" id="motivation"><span class="header-section-number">3</span> Motivation<a href="#motivation" class="self-link"></a></h1>
<p>There has been significantly increased attention to safety and
security in C++ over the last few years, as exemplified by the
well-known <a href="https://www.whitehouse.gov/wp-content/uploads/2024/02/Final-ONCD-Technical-Report.pdf">White
House report</a> and numerous recent security-related proposals.</p>
<p>While it is important to explore ways to make <em>new</em> code
safer, we believe that the highest priority to deliver immediate
real-world value should be to make <em>existing</em> code safer with
minimal or no effort on behalf of users. Indeed, the amount of existing
security-critical C++ code is so large that rewriting it or modifying it
is both economically unviable and dangerous given the risk of
introducing new issues.</p>
<p>There have been a few proposals accepted recently that eliminate some
cases of undefined behavior in the core language. The standard library
also contains many instances of undefined behavior, some of which is a
direct source of security vulnerabilities; addressing those is often
trivial, can be done with low overhead and almost no work on behalf of
users.</p>
<p>In fact, at the moment all three major library implementations have
some notion of a hardened or debug mode. This clearly shows interest,
both from users and from implementers, in having a safer mode for the
standard library. However, we believe these efforts would be vastly more
useful if they were standardized and provided portable, cross-platform
guarantees to users; as it stands, implementations differ in levels of
coverage, performance guarantees and ways to enable the safer mode.</p>
<p>Finally, leaving security of the library to be a pure vendor
extension fails to position ISO C++ as providing a credible solution for
code bases with formal security requirements. We believe that formally
requiring the basic safety guarantees that most implementations already
provide in one way or another could make a significant difference from
the point of view of anyone writing or following safety and security
coding standards and guidelines.</p>
<h1 data-number="4" id="deployment-experience"><span class="header-section-number">4</span> Deployment experience<a href="#deployment-experience" class="self-link"></a></h1>
<p>All three major implementations provide vendor-specific ways of
enabling library assertions as proposed in this paper, today.</p>
<ul>
<li>We have experience deploying hardening on Apple platforms in several
existing codebases.</li>
<li>Google recently published <a href="https://security.googleblog.com/2024/11/retrofitting-spatial-safety-to-hundreds.html">an
article</a> where they describe their experience with deploying this
very technology to hundreds of millions of lines of code. They reported
a performance impact as low as 0.3% and finding over 1000 bugs,
including security critical ones.</li>
<li>Google Andromeda published <a href="https://bughunters.google.com/blog/6368559657254912/llvm-s-rfc-c-buffer-hardening-at-google">an
article</a> ~1 year ago about their successful experience enabling
hardening.</li>
<li>The libc++ maintainers have received numerous informal reports of
hardening being turned on and helping find bugs in codebases.</li>
</ul>
<p>Overall, standard library hardening has been a huge success, in fact
we never expected so much success. The reception has been overwhelmingly
positive and while the quality of implementation will never be perfect,
we are working hard to expand the scope of hardening in libc++, to
improve its performance and the user experience.</p>
<h1 data-number="5" id="design-overview"><span class="header-section-number">5</span> Design overview<a href="#design-overview" class="self-link"></a></h1>
<p>At a high level, this proposal consists of two parts:</p>
<ul>
<li>Annotate <em>some</em> existing library preconditions as
<em>hardened</em>.</li>
<li>Define the notion of a <em>hardened implementation</em>. In a
hardened implementation, <em>hardened preconditions</em> are checked at
runtime and violating them is a contract violation.</li>
</ul>
<p>There are a few important aspects to the proposed design:</p>
<ul>
<li>In a <em>hardened implementation</em>, it is not possible to “turn
off” these precondition checks by using the
<code class="sourceCode cpp">ignore</code> semantic. Since we specify
that violating a <em>hardened precondition</em> is a contract violation,
we are already past the point where
<code class="sourceCode cpp">ignore</code> could bypass the check.</li>
<li>We only propose to formally check (some of the) existing function
preconditions, not to add any new preconditions. As a drive-by, we also
make a few existing preconditions more explicit in the specification
(e.g. <code class="sourceCode cpp">vector<span class="op">::</span><span class="kw">operator</span><span class="op">[]</span></code>
only has implicit preconditions via iterator validity).</li>
<li>Hardening deals exclusively with preconditions that must be checked
at runtime. Thus, performance overhead is an important constraint.</li>
<li>Hardening is intended to avoid requiring changes to an
implementation’s ABI. In particular, the intent is to make it possible
for implementations to allow mixing hardened and unhardened code in the
same program, if they wish to do so.</li>
<li>Hardening needs to be lightweight enough to be used in production
environments. In our experience, a debug-only approach is not sufficient
to really move the needle security-wise. Thus, the goal is to identify
the minimal set of checks that would deliver the most value to users
while requiring minimal overhead, with a particular focus on memory
safety as a major source of security vulnerabilities. Checking
<em>all</em> preconditions in the library is an explicit non-goal, and
would be impossible for many semantic requirements anyway.</li>
</ul>
<p>To reiterate the last point, an important design principle is that
hardening needs to be lightweight enough for production use by a wide
variety of real-world programs. In our experience in libc++, a small set
of checks that is widely used delivers far more value than a more
extensive set of checks that is only enabled by select few users.
Thankfully, many of the most valuable checks, such as checking for
out-of-bounds access in standard containers, also happen to be
relatively cheap.</p>
<h1 data-number="6" id="hardened-preconditions"><span class="header-section-number">6</span> Hardened preconditions<a href="#hardened-preconditions" class="self-link"></a></h1>
<p>To specify hardening in the Standard, this proposal introduces the
notion of a <em>hardened precondition</em>. A <em>hardened
precondition</em> is a precondition that results in a contract violation
in a <em>hardened implementation</em>. Adding hardening to the library
largely consists of turning some of the existing preconditions into
<em>hardened preconditions</em> in the specification. For example:</p>
<p><span class="marginalizedparent"><a class="marginalized">(24.7.2.2.6)</a></span>
Element access <span>23.7.2.2.6
<a href="https://wg21.link/span.elem">[span.elem]</a></span></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">constexpr</span> reference <span class="kw">operator</span><span class="op">[](</span>size_type idx<span class="op">)</span> <span class="kw">const</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
<span class="add" style="color: #006e28"><ins>Hardened</ins></span>
Preconditions: <code class="sourceCode cpp">idx <span class="op">&lt;</span> size<span class="op">()</span></code>
is <code class="sourceCode cpp"><span class="kw">true</span></code>.</p>
<p>In the initial proposal, we decide to focus on hardened preconditions
that prevent out-of-bounds memory access, i.e., compromise the memory
safety of the program. These are some of the most valuable for the user
since they help prevent potential security vulnerabilities; many of them
are also relatively cheap to implement. More hardened preconditions can
potentially be added in the future, but the intent is for their number
to be limited to keep hardening viable for production use. Specifically,
the proposal is to add hardened preconditions to:</p>
<ul>
<li>Accessors of sequence containers,
<code class="sourceCode cpp">std<span class="op">::</span>span</code>,
<code class="sourceCode cpp">std<span class="op">::</span>mdspan</code>,
<code class="sourceCode cpp">std<span class="op">::</span>string</code>,
<code class="sourceCode cpp">std<span class="op">::</span>string_view</code>
and other similar classes that might attempt to access non-existent
elements
(e.g. <code class="sourceCode cpp">back<span class="op">()</span></code>
on an empty container or <code class="sourceCode cpp"><span class="kw">operator</span><span class="op">[]</span></code>
with an invalid index).</li>
<li>Modifiers of sequence containers and string classes that assume the
container to be non-empty
(e.g. <code class="sourceCode cpp">pop_back<span class="op">()</span></code>).</li>
<li>Accessors of <code class="sourceCode cpp">optional</code> and
<code class="sourceCode cpp">expected</code> that expect the object to
be non-empty.</li>
</ul>
<p>In our experience, hardening all of these operations is trivial to
implement and provides significant security value.</p>
<h1 data-number="7" id="enabling-hardening"><span class="header-section-number">7</span> Enabling hardening<a href="#enabling-hardening" class="self-link"></a></h1>
<p>Much like a freestanding implementation, the way to request a
<em>hardened</em> implementation is left for the implementation to
define. For example, similarly to <code class="sourceCode cpp"><span class="op">-</span>ffreestanding</code>, we
expect that most toolchains would provide a compiler flag like
<code class="sourceCode cpp"><span class="op">-</span>fhardened</code>,
but other alternatives like a <code class="sourceCode cpp"><span class="op">-</span>D_LIBCPP_HARDENING_MODE<span class="op">=&lt;</span>mode<span class="op">&gt;</span></code>
macro would also be conforming. If this proposal gets accepted, we
expect implementations to converge on a portable mechanism. Other
details like whether hardened implementations and non-hardened
implementations can be mixed in different translation units are
intentionally left unspecified, to avoid overconstraining the
implementations.</p>
<h1 data-number="8" id="relationship-to-contracts-profiles-and-erroneous-behavior"><span class="header-section-number">8</span> Relationship to Contracts,
Profiles, and Erroneous Behavior<a href="#relationship-to-contracts-profiles-and-erroneous-behavior" class="self-link"></a></h1>
<h2 data-number="8.1" id="contracts"><span class="header-section-number">8.1</span> Contracts<a href="#contracts" class="self-link"></a></h2>
<p>Contracts is a new (in-progress) language feature that allows
expressing preconditions and much more, with a lot of flexibility on
what happens when an assertion is not satisfied. In the latest revision
of this paper, we decided to base <em>hardened preconditions</em> on
contract violations for several reasons:</p>
<ul>
<li>It provides a unifying framework for specifying what should be done
when “something goes wrong” both at the language and the library level.
A unified mechanism is something that our current hardening clients have
been repeatedly requesting.</li>
<li>It provides flexibility for handling contract violations in a way
that best suits the user. In particular, our deployment experience has
made it clear that different users have different requirements, and that
e.g. the weaker <code class="sourceCode cpp">observe</code> semantics
can be extremely useful to allow deploying this at scale.</li>
</ul>
<p>It is useful to note that we don’t require implementations to
actually implement these checks as contract assertions. Implementations
are free to implement precondition checking however they see fit (e.g. a
macro), however they are required to employ the contract violation
handling mechanism when a precondition is not satisfied.</p>
<p>Note that if Contracts were to not be pursued anymore, this feature
could easily be reworded in terms of a guaranteed termination in an
implementation-defined way, or using Erroneous Behavior. We are not
strongly attached to the exact mechanism used to implement this, but we
find that Contracts is a nearly perfect fit.</p>
<h2 data-number="8.2" id="profiles"><span class="header-section-number">8.2</span> Profiles<a href="#profiles" class="self-link"></a></h2>
<p>The various Profiles proposals introduce a framework to specify sets
of safety guarantees (such as a type safety profile or an invalidation
profile). If profiles become a part of the Standard in the future,
hardening can most likely be formulated as an additional profile; this
would formalize how hardening is turned on and off.</p>
<p>However, we feel strongly that a hardening mode as specified in this
paper standardizes existing practice and delivers value today without
waiting for a larger and still experimental language feature.</p>
<h2 data-number="8.3" id="erroneous-behavior"><span class="header-section-number">8.3</span> Erroneous Behavior<a href="#erroneous-behavior" class="self-link"></a></h2>
<p>While Erroneous Behavior is a way to clearly mark some code as
incorrect in the specification, it does not clearly specify
<em>what</em> should happen in case of EB. For example, a conforming
behavior for <code class="sourceCode cpp">vector<span class="op">::</span><span class="kw">operator</span><span class="op">[]</span></code>
being called out-of-bounds under EB would be to return the last element
of the vector instead. While that is well-defined behavior, we feel that
it is not especially useful behavior and that is certainly not what our
users are looking for. In contrast, the Contracts facilities provide a
well-defined and flexible framework to handle this.</p>
<h1 data-number="9" id="proposed-wording-partial"><span class="header-section-number">9</span> Proposed wording (partial)<a href="#proposed-wording-partial" class="self-link"></a></h1>
<!-- Change in 7.5.4.1 [expr.prim.id.unqual] paragraph 2: -->
<p>Add a new paragraph to <span>4.1
<a href="https://wg21.link/intro.compliance">[intro.compliance]</a></span>
after paragraph 7 as indicated:</p>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">7</a></span>
Two kinds of implementations are defined: a <em>hosted
implementation</em> and a <em>freestanding implementation.</em> A
freestanding implementation is one in which execution may take place
without the benefit of an operating system. A hosted implementation
supports all the facilities described in this document, while a
freestanding implementation supports the entire C++ language described
in <code class="sourceCode cpp"><span class="op">[</span>lex<span class="op">]</span></code>
through <code class="sourceCode cpp"><span class="op">[</span>cpp<span class="op">]</span></code>
and the subset of the library facilities described in <code class="sourceCode cpp"><span class="op">[</span>compliance<span class="op">]</span></code>.</p>
</blockquote>
<div class="add" style="color: #006e28">

<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">8</a></span>
Additionally, an implementation can be a <em>hardened
implementation</em>. A hardened implementation is one in which violating
a <em>hardened precondition</em> is a contract violation.</p>
</blockquote>

</div>
<p>Add a new element to <span>16.3.2.4
<a href="https://wg21.link/structure.specifications">[structure.specifications]</a></span>
after element 3.3 as indicated:</p>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">(3.3)</a></span>
<em>Preconditions</em>: the conditions that the function assumes to hold
whenever it is called; violation of any preconditions results in
undefined behavior.</p>
</blockquote>
<div class="add" style="color: #006e28">

<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">(3.4)</a></span>
<em>Hardened Preconditions</em>: the conditions that the function
assumes to hold whenever it is called; violation of any hardened
preconditions results in a contract violation in a hardened
implementation, and undefined behavior otherwise.</p>
</blockquote>

</div>
<p>Modify <span>23.7.2.2.6
<a href="https://wg21.link/span.elem">[span.elem]</a></span> around
paragraph 1 as indicated:</p>
<blockquote>
<p><code class="sourceCode cpp"><span class="kw">constexpr</span> reference <span class="kw">operator</span><span class="op">[](</span>size_type idx<span class="op">)</span> <span class="kw">const</span>;</code></p>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
<em><span class="add" style="color: #006e28"><ins>Hardened</ins></span>
Preconditions</em>: <code class="sourceCode cpp">idx <span class="op">&lt;</span> size<span class="op">()</span></code>
is <code class="sourceCode cpp"><span class="kw">true</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span>
<em>Returns</em>: <code class="sourceCode cpp"><span class="op">*(</span>data<span class="op">()</span> <span class="op">+</span> idx<span class="op">)</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span>
<em>Throws</em>: Nothing.</p>
</blockquote>
<p>Modify <span>27.3.3.6
<a href="https://wg21.link/string.view.access">[string.view.access]</a></span>
around paragraph 1 as indicated:</p>
<blockquote>
<p><code class="sourceCode cpp"><span class="kw">constexpr</span> const_reference <span class="kw">operator</span><span class="op">[](</span>size_type pos<span class="op">)</span> <span class="kw">const</span>;</code></p>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
<em><span class="add" style="color: #006e28"><ins>Hardened</ins></span>
Preconditions</em>: <code class="sourceCode cpp">pos <span class="op">&lt;</span> size<span class="op">()</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span>
<em>Returns</em>: <code class="sourceCode cpp">data_<span class="op">[</span>pos<span class="op">]</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span>
<em>Throws</em>: Nothing.</p>
</blockquote>
<p>Modify <span>23.2.4
<a href="https://wg21.link/sequence.reqmts">[sequence.reqmts]</a></span>
around paragraph 117 as indicated:</p>
<blockquote>
<p><code class="sourceCode cpp">a<span class="op">[</span>n<span class="op">]</span></code></p>
<p><span class="marginalizedparent"><a class="marginalized">117</a></span>
<em>Result</em>: <code class="sourceCode cpp">reference</code>;
<code class="sourceCode cpp">const_reference</code> for constant
<code class="sourceCode cpp">a</code></p>
<div class="add" style="color: #006e28">
<p><span class="marginalizedparent"><a class="marginalized">118</a></span>
<em>Hardened Preconditions</em>:
<code class="sourceCode default">n &lt; a.size();</code>
<!-- n <= a.size() for basic_string --></p>
</div>
<p><span class="marginalizedparent"><a class="marginalized">119</a></span>
<em>Effects</em>: Equivalent to: <code class="sourceCode cpp"><span class="cf">return</span> <span class="op">*(</span>a<span class="op">.</span>begin<span class="op">()</span> <span class="op">+</span> n<span class="op">)</span>;</code></p>
<p><span class="marginalizedparent"><a class="marginalized">120</a></span>
<em>Remarks</em>: Required for
<code class="sourceCode cpp">basic_string</code>,
<code class="sourceCode cpp">array</code>,
<code class="sourceCode cpp">deque</code>,
<code class="sourceCode cpp">inplace_vector</code>, and
<code class="sourceCode cpp">vector</code>.</p>
</blockquote>
<p>Modify <span>22.8.6.6
<a href="https://wg21.link/expected.object.obs">[expected.object.obs]</a></span>
paragraph 1 as indicated:</p>
<blockquote>
<p><code class="sourceCode cpp"><span class="kw">constexpr</span> <span class="kw">const</span> T<span class="op">*</span> <span class="kw">operator</span><span class="op">-&gt;()</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</code></p>
<p><code class="sourceCode cpp"><span class="kw">constexpr</span> T<span class="op">*</span> <span class="kw">operator</span><span class="op">-&gt;()</span> <span class="kw">noexcept</span>;</code></p>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
<em><span class="add" style="color: #006e28"><ins>Hardened</ins></span>
Preconditions</em>:
<code class="sourceCode cpp">has_value<span class="op">()</span></code>
is <code class="sourceCode cpp"><span class="kw">true</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span>
<em>Returns</em>: <code class="sourceCode cpp">addressof<span class="op">(</span>val<span class="op">)</span></code>.</p>
</blockquote>
<p>Modify <span>22.8.6.6
<a href="https://wg21.link/expected.object.obs">[expected.object.obs]</a></span>
paragraph 3 as indicated:</p>
<blockquote>
<p><code class="sourceCode cpp"><span class="kw">constexpr</span> <span class="kw">const</span> T<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">*()</span> <span class="kw">const</span> <span class="op">&amp;</span> <span class="kw">noexcept</span>;</code></p>
<p><code class="sourceCode cpp"><span class="kw">constexpr</span> T<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">*()</span> <span class="op">&amp;</span> <span class="kw">noexcept</span>;</code></p>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span>
<em><span class="add" style="color: #006e28"><ins>Hardened</ins></span>
Preconditions</em>:
<code class="sourceCode cpp">has_value<span class="op">()</span></code>
is <code class="sourceCode cpp"><span class="kw">true</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span>
<em>Returns</em>: <code class="sourceCode cpp">val</code>.</p>
</blockquote>
<p>Modify <span>22.8.6.6
<a href="https://wg21.link/expected.object.obs">[expected.object.obs]</a></span>
paragraph 5 as indicated:</p>
<blockquote>
<p><code class="sourceCode cpp"><span class="kw">constexpr</span> T<span class="op">&amp;&amp;</span> <span class="kw">operator</span><span class="op">*()</span> <span class="op">&amp;&amp;</span> <span class="kw">noexcept</span>;</code></p>
<p><code class="sourceCode cpp"><span class="kw">constexpr</span> <span class="kw">const</span> T<span class="op">&amp;&amp;</span> <span class="kw">operator</span><span class="op">*()</span> <span class="kw">const</span> <span class="op">&amp;&amp;</span> <span class="kw">noexcept</span>;</code></p>
<p><span class="marginalizedparent"><a class="marginalized">5</a></span>
<em><span class="add" style="color: #006e28"><ins>Hardened</ins></span>
Preconditions</em>:
<code class="sourceCode cpp">has_value<span class="op">()</span></code>
is <code class="sourceCode cpp"><span class="kw">true</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">6</a></span>
<em>Returns</em>: <code class="sourceCode cpp">std<span class="op">::</span>move<span class="op">(</span>val<span class="op">)</span></code>.</p>
</blockquote>
<p>Modify <span>22.5.3.7
<a href="https://wg21.link/optional.observe">[optional.observe]</a></span>
paragraph 1 as indicated:</p>
<blockquote>
<p><code class="sourceCode cpp"><span class="kw">constexpr</span> <span class="kw">const</span> T<span class="op">*</span> <span class="kw">operator</span><span class="op">-&gt;()</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</code></p>
<p><code class="sourceCode cpp"><span class="kw">constexpr</span> T<span class="op">*</span> <span class="kw">operator</span><span class="op">-&gt;()</span> <span class="kw">noexcept</span>;</code></p>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
<em><span class="add" style="color: #006e28"><ins>Hardened</ins></span>
Preconditions</em>: <code class="sourceCode cpp"><span class="op">*</span><span class="kw">this</span></code>
contains a value.</p>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span>
<em>Returns</em>:
<code class="sourceCode cpp"><span class="op">*</span>val</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span>
<em>Remarks</em>: These functions are
<code class="sourceCode cpp"><span class="kw">constexpr</span></code>
functions.</p>
</blockquote>
<p>Modify <span>22.5.3.7
<a href="https://wg21.link/optional.observe">[optional.observe]</a></span>
paragraph 4 as indicated:</p>
<blockquote>
<p><code class="sourceCode cpp"><span class="kw">constexpr</span> <span class="kw">const</span> T<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">*()</span> <span class="kw">const</span> <span class="op">&amp;</span> <span class="kw">noexcept</span>;</code></p>
<p><code class="sourceCode cpp"><span class="kw">constexpr</span> T<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">*()</span> <span class="op">&amp;</span> <span class="kw">noexcept</span>;</code></p>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span>
<em><span class="add" style="color: #006e28"><ins>Hardened</ins></span>
Preconditions</em>: <code class="sourceCode cpp"><span class="op">*</span><span class="kw">this</span></code>
contains a value.</p>
<p><span class="marginalizedparent"><a class="marginalized">5</a></span>
<em>Returns</em>:
<code class="sourceCode cpp"><span class="op">*</span>val</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">6</a></span>
<em>Remarks</em>: These functions are
<code class="sourceCode cpp"><span class="kw">constexpr</span></code>
functions.</p>
</blockquote>
<p>Modify <span>22.5.3.7
<a href="https://wg21.link/optional.observe">[optional.observe]</a></span>
paragraph 7 as indicated:</p>
<blockquote>
<p><code class="sourceCode cpp"><span class="kw">constexpr</span> T<span class="op">&amp;&amp;</span> <span class="kw">operator</span><span class="op">*()</span> <span class="op">&amp;&amp;</span> <span class="kw">noexcept</span>;</code></p>
<p><code class="sourceCode cpp"><span class="kw">constexpr</span> <span class="kw">const</span> T<span class="op">&amp;&amp;</span> <span class="kw">operator</span><span class="op">*()</span> <span class="kw">const</span> <span class="op">&amp;&amp;</span> <span class="kw">noexcept</span>;</code></p>
<p><span class="marginalizedparent"><a class="marginalized">7</a></span>
<em><span class="add" style="color: #006e28"><ins>Hardened</ins></span>
Preconditions</em>: <code class="sourceCode cpp"><span class="op">*</span><span class="kw">this</span></code>
contains a value.</p>
<p><span class="marginalizedparent"><a class="marginalized">8</a></span>
<em>Effects</em>: Equivalent to: <code class="sourceCode cpp"><span class="cf">return</span> std<span class="op">::</span>move<span class="op">(*</span>val<span class="op">)</span>;</code></p>
</blockquote>
<!--
# Proposed wording approach

- optional
- expected

In [`intro.compliance`](https://eel.is/c++draft/intro.compliance), add a new paragraph that states:

> An implementation can be hardened or unhardened. A hardened implementation is one in which violating a hardened precondition results in program termination and does not result in undefined behavior. In an unhardened implementation violating a hardened precondition is equivalent to violating an unhardened precondition. A conforming implementation shall provide a hardened implementation.

In [`structure.specifications`](http://eel.is/c++draft/description#structure.specifications-3.3), add a new element called “Hardened Preconditions” (the exact name is subject to discussion) which says:

> Hardened preconditions: the conditions that the function assumes to hold whenever it is called. In a hardened implementation, violation of any hardened preconditions results in program termination in an implementation-defined way; otherwise, the violation results in undefined behavior.

Then, change a few places such as [`sequence.reqmts`](http://eel.is/c++draft/sequence.reqmts#117) to either add Hardened Preconditions, or turn existing “Preconditions” into “Hardened Preconditions” (for example, [`span.elem`](http://eel.is/c++draft/views.span#span.elem-1)). Note, however, that adding Hardened Preconditions would only be made to make existing implicit preconditions explicit; the scope of this proposal is only to add checking to existing preconditions, whether they are specified explicitly or implicitly, not to add any actual new preconditions.
-->
<h1 data-number="10" id="suggested-polls"><span class="header-section-number">10</span> Suggested polls<a href="#suggested-polls" class="self-link"></a></h1>
<ul>
<li>Are we interested in standardizing some portable notion of hardening
for the Standard Library (as opposed to letting these efforts be vendor
extensions)?</li>
<li>Are we happy with hardening being phrased in terms of contract
violations?</li>
<li>Are we happy with advancing this paper independently from Profiles
proposals (understanding they may be reunited in the future)?</li>
</ul>
</div>
</div>
</body>
</html>
