<!DOCTYPE html>
<html lang="en"><head>
  <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
  <meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport">
  <title>P3085R1: noexcept policy for SD-9 (throws nothing)</title>
<style data-fill-with="stylesheet">/******************************************************************************
 *                   Style sheet for the W3C specifications                   *
 *
 * Special classes handled by this style sheet include:
 *
 * Indices
 *   - .toc for the Table of Contents (<ol class="toc">)
 *     + <span class="secno"> for the section numbers
 *   - #toc for the Table of Contents (<nav id="toc">)
 *   - ul.index for Indices (<a href="#ref">term</a><span>, in § N.M</span>)
 *   - table.index for Index Tables (e.g. for properties or elements)
 *
 * Structural Markup
 *   - table.data for general data tables
 *     -> use 'scope' attribute, <colgroup>, <thead>, and <tbody> for best results !
 *     -> use <table class='complex data'> for extra-complex tables
 *     -> use <td class='long'> for paragraph-length cell content
 *     -> use <td class='pre'> when manual line breaks/indentation would help readability
 *   - dl.switch for switch statements
 *   - ol.algorithm for algorithms (helps to visualize nesting)
 *   - .figure and .caption (HTML4) and figure and figcaption (HTML5)
 *     -> .sidefigure for right-floated figures
 *   - ins/del
 *     -> ins/del.c### for candidate and proposed changes (amendments)
 *
 * Code
 *   - pre and code
 *
 * Special Sections
 *   - .note       for informative notes             (div, p, span, aside, details)
 *   - .example    for informative examples          (div, p, pre, span)
 *   - .issue      for issues                        (div, p, span)
 *   - .advisement for loud normative statements     (div, p, strong)
 *   - .annoying-warning for spec obsoletion notices (div, aside, details)
 *   - .correction for "candidate corrections"       (div, aside, details, section)
 *   - .addition   for "candidate additions"         (div, aside, details, section)
 *   - .correction.proposed for "proposed corrections" (div, aside, details, section)
 *   - .addition.proposed   for "proposed additions"   (div, aside, details, section)
 *
 * Definition Boxes
 *   - pre.def   for WebIDL definitions
 *   - table.def for tables that define other entities (e.g. CSS properties)
 *   - dl.def    for definition lists that define other entitles (e.g. HTML elements)
 *
 * Numbering
 *   - .secno for section numbers in .toc and headings (<span class='secno'>3.2</span>)
 *   - .marker for source-inserted example/figure/issue numbers (<span class='marker'>Issue 4</span>)
 *   - ::before styled for CSS-generated issue/example/figure numbers:
 *     -> Documents wishing to use this only need to add
 *        figcaption::before,
 *        .caption::before { content: "Figure "  counter(figure) " ";  }
 *        .example::before { content: "Example " counter(example) " "; }
 *        .issue::before   { content: "Issue "   counter(issue) " ";   }
 *
 * Header Stuff (ignore, just don't conflict with these classes)
 *   - .head for the header
 *   - .copyright for the copyright
 *
 * Outdated warning for old specs
 *
 * Miscellaneous
 *   - .overlarge for things that should be as wide as possible, even if
 *     that overflows the body text area. This can be used on an item or
 *     on its container, depending on the effect desired.
 *     Note that this styling basically doesn't help at all when printing,
 *     since A4 paper isn't much wider than the max-width here.
 *     It's better to design things to fit into a narrower measure if possible.
 *
 *   - js-added ToC jump links (see fixup.js)
 *
 ******************************************************************************/

/* color variables included separately for reliability */

/******************************************************************************/
/*                                    Body                                    */
/******************************************************************************/

	html {
	}

	body {
		counter-reset: example figure issue;

		/* Layout */
		max-width: 50em;			  /* limit line length to 50em for readability   */
		margin: 0 auto;				/* center text within page                    */
		padding: 1.6em 1.5em 2em 50px; /* assume 16px font size for downlevel clients */
		padding: 1.6em 1.5em 2em calc(26px + 1.5em); /* leave space for status flag    */

		/* Typography */
		line-height: 1.5;
		font-family: sans-serif;
		widows: 2;
		orphans: 2;
		word-wrap: break-word;
		overflow-wrap: break-word;
		hyphens: auto;

		color: black;
		color: var(--text);
		background: white top left fixed no-repeat;
		background: var(--bg) top left fixed no-repeat;
		background-size: 25px auto;
	}


/******************************************************************************/
/*                         Front Matter & Navigation                          */
/******************************************************************************/

/** Header ********************************************************************/

	div.head { margin-bottom: 1em; }
	div.head hr { border-style: solid; }

	div.head h1 {
		font-weight: bold;
		margin: 0 0 .1em;
		font-size: 220%;
	}

	div.head h2 { margin-bottom: 1.5em;}

/** W3C Logo ******************************************************************/

	.head .logo {
		float: right;
		margin: 0.4rem 0 0.2rem .4rem;
	}

	.head img[src*="logos/W3C"] {
		display: block;
		border: solid #1a5e9a;
		border: solid var(--logo-bg);
		border-width: .65rem .7rem .6rem;
		border-radius: .4rem;
		background: #1a5e9a;
		background: var(--logo-bg);
		color: white;
		color: var(--logo-text);
		font-weight: bold;
	}

	.head a:hover > img[src*="logos/W3C"],
	.head a:focus > img[src*="logos/W3C"] {
		opacity: .8;
	}

	.head a:active > img[src*="logos/W3C"] {
		background: #c00;
		background: var(--logo-active-bg);
		border-color: #c00;
		border-color: var(--logo-active-bg);
	}

	/* see also additional rules in Link Styling section */

/** Copyright *****************************************************************/

	p.copyright,
	p.copyright small { font-size: small; }

/** Back to Top / ToC Toggle **************************************************/

	@media print {
		#toc-nav {
			display: none;
		}
	}
	@media not print {
		#toc-nav {
			position: fixed;
			z-index: 3;
			bottom: 0; left: 0;
			margin: 0;
			min-width: 1.33em;
			border-top-right-radius: 2rem;
			box-shadow: 0 0 2px;
			font-size: 1.5em;
		}
		#toc-nav > a {
			display: block;
			white-space: nowrap;

			height: 1.33em;
			padding: .1em 0.3em;
			margin: 0;

			box-shadow: 0 0 2px;
			border: none;
			border-top-right-radius: 1.33em;

			color: #707070;
			color: var(--tocnav-normal-text);
			background: white;
			background: var(--tocnav-normal-bg);
		}
		#toc-nav > a:hover,
		#toc-nav > a:focus {
			color: black;
			color: var(--tocnav-hover-text);
			background: #f8f8f8;
			background: var(--tocnav-hover-bg);
		}
		#toc-nav > a:active {
			color: #c00;
			color: var(--tocnav-active-text);
			background: white;
			background: var(--tocnav-active-bg);
		}

		#toc-nav > #toc-jump {
			padding-bottom: 2em;
			margin-bottom: -1.9em;
		}

		/* statusbar gets in the way on keyboard focus; remove once browsers fix */
		#toc-nav > a[href="#toc"]:not(:hover):focus:last-child {
			padding-bottom: 1.5rem;
		}

		#toc-nav:not(:hover) > a:not(:focus) > span + span {
			/* Ideally this uses :focus-within on #toc-nav */
			display: none;
		}
		#toc-nav > a > span + span {
			padding-right: 0.2em;
		}
	}

/** ToC Sidebar ***************************************************************/

	/* Floating sidebar */
	@media screen {
		body.toc-sidebar #toc {
			position: fixed;
			top: 0; bottom: 0;
			left: 0;
			width: 23.5em;
			max-width: 80%;
			max-width: calc(100% - 2em - 26px);
			overflow: auto;
			padding: 0 1em;
			padding-left: 42px;
			padding-left: calc(1em + 26px);
			color: black;
			color: var(--tocsidebar-text);
			background: inherit;
			background-color: #f7f8f9;
			background-color: var(--tocsidebar-bg);
			z-index: 1;
			box-shadow: -.1em 0 .25em rgba(0,0,0,.1) inset;
			box-shadow: -.1em 0 .25em var(--tocsidebar-shadow) inset;
		}
		body.toc-sidebar #toc h2 {
			margin-top: .8rem;
			font-variant: small-caps;
			font-variant: all-small-caps;
			text-transform: lowercase;
			font-weight: bold;
			color: gray;
			color: hsla(203,20%,40%,.7);
			color: var(--tocsidebar-heading-text);
		}
		body.toc-sidebar #toc-jump:not(:focus) {
			width: 0;
			height: 0;
			padding: 0;
			position: absolute;
			overflow: hidden;
		}
	}
	/* Hide main scroller when only the ToC is visible anyway */
	@media screen and (max-width: 28em) {
		body.toc-sidebar {
			overflow: hidden;
		}
	}

	/* Sidebar with its own space */
	@media screen and (min-width: 78em) {
		body:not(.toc-inline) #toc {
			position: fixed;
			top: 0; bottom: 0;
			left: 0;
			width: 23.5em;
			overflow: auto;
			padding: 0 1em;
			padding-left: 42px;
			padding-left: calc(1em + 26px);
			color: black;
			color: var(--tocsidebar-text);
			background: inherit;
			background-color: #f7f8f9;
			background-color: var(--tocsidebar-bg);
			z-index: 1;
			box-shadow: -.1em 0 .25em rgba(0,0,0,.1) inset;
			box-shadow: -.1em 0 .25em var(--tocsidebar-shadow) inset;
		}
		body:not(.toc-inline) #toc h2 {
			margin-top: .8rem;
			font-variant: small-caps;
			font-variant: all-small-caps;
			text-transform: lowercase;
			font-weight: bold;
			color: gray;
			color: hsla(203,20%,40%,.7);
			color: var(--tocsidebar-heading-text);
		}

		body:not(.toc-inline) {
			padding-left: 29em;
		}
		/* See also Overflow section at the bottom */

		body:not(.toc-inline) #toc-jump:not(:focus) {
			width: 0;
			height: 0;
			padding: 0;
			position: absolute;
			overflow: hidden;
		}
	}
	@media screen and (min-width: 90em) {
		body:not(.toc-inline) {
			margin: 0 4em;
		}
	}

/******************************************************************************/
/*                                Sectioning                                  */
/******************************************************************************/

/** Headings ******************************************************************/

	h1, h2, h3, h4, h5, h6, dt {
		page-break-after: avoid;
		page-break-inside: avoid;
		font: 100% sans-serif;   /* Reset all font styling to clear out UA styles */
		font-family: inherit;	/* Inherit the font family. */
		line-height: 1.2;		/* Keep wrapped headings compact */
		hyphens: manual;		/* Hyphenated headings look weird */
	}

	h2, h3, h4, h5, h6 {
		margin-top: 3rem;
	}

	h1, h2, h3 {
		color: #005A9C;
		color: var(--heading-text);
	}

	h1 { font-size: 170%; }
	h2 { font-size: 140%; }
	h3 { font-size: 120%; }
	h4 { font-weight: bold; }
	h5 { font-style: italic; }
	h6 { font-variant: small-caps; }
	dt { font-weight: bold; }

/** Subheadings ***************************************************************/

	h1 + h2,
	#profile-and-date {
		/* #profile-and-date is a subtitle in an H2 under the H1 */
		margin-top: 0;
	}
	h2 + h3,
	h3 + h4,
	h4 + h5,
	h5 + h6 {
		margin-top: 1.2em; /* = 1 x line-height */
	}

/** Section divider ***********************************************************/

	:not(.head) > :not(.head) + hr {
		font-size: 1.5em;
		text-align: center;
		margin: 1em auto;
		height: auto;
		color: black;
		color: var(--hr-text);
		border: transparent solid 0;
		background: transparent;
	}
	:not(.head) > hr::before {
		content: "\2727\2003\2003\2727\2003\2003\2727";
	}

/******************************************************************************/
/*                            Paragraphs and Lists                            */
/******************************************************************************/

	p {
		margin: 1em 0;
	}

	dd > p:first-child,
	li > p:first-child {
		margin-top: 0;
	}

	ul, ol {
		margin-left: 0;
		padding-left: 2em;
	}

	li {
		margin: 0.25em 0 0.5em;
		padding: 0;
	}

	dl dd {
		margin: 0 0 .5em 2em;
	}

	.head dd + dd { /* compact for header */
		margin-top: -.5em;
	}

	/* Style for algorithms */
	ol.algorithm ol:not(.algorithm),
	.algorithm > ol ol:not(.algorithm) {
	border-left: 0.5em solid #DEF;
	border-left: 0.5em solid var(--algo-border);
	}

	/* Put nice boxes around each algorithm. */
	[data-algorithm]:not(.heading) {
	 padding: .5em;
	 border: thin solid #ddd;
	 border: thin solid var(--algo-border);
	 border-radius: .5em;
	 margin: .5em calc(-0.5em - 1px);
	}
	[data-algorithm]:not(.heading) > :first-child {
	 margin-top: 0;
	}
	[data-algorithm]:not(.heading) > :last-child {
	 margin-bottom: 0;
	}

	/* Style for switch/case <dl>s */
	dl.switch > dd > ol.only,
	dl.switch > dd > .only > ol {
	margin-left: 0;
	}
	dl.switch > dd > ol.algorithm,
	dl.switch > dd > .algorithm > ol {
	margin-left: -2em;
	}
	dl.switch {
	padding-left: 2em;
	}
	dl.switch > dt {
	text-indent: -1.5em;
	margin-top: 1em;
	}
	dl.switch > dt + dt {
	margin-top: 0;
	}
	dl.switch > dt::before {
	content: '\21AA';
	padding: 0 0.5em 0 0;
	display: inline-block;
	width: 1em;
	text-align: right;
	line-height: 0.5em;
	}

/** Terminology Markup ********************************************************/


/******************************************************************************/
/*                                 Inline Markup                              */
/******************************************************************************/

/** Terminology Markup ********************************************************/
	dfn   { /* Defining instance */
		font-weight: bolder;
	}
	a > i { /* Instance of term */
		font-style: normal;
	}
	dt dfn code, code.idl {
		font-size: inherit;
	}
	dfn var {
		font-style: normal;
	}

/** Change Marking ************************************************************/

	del {
		color: #aa0000;
		color: var(--del-text);
		background: transparent;
		background: var(--del-bg);
		text-decoration: line-through;
	}
	ins {
		color: #006100;
		color: var(--ins-text);
		background: transparent;
		background: var(--ins-bg);
		text-decoration: underline;
	}

	/* for amendments (candidate/proposed changes) */

	.amendment ins, .correction ins, .addition ins,
	ins[class^=c] {
		text-decoration-style: dotted;
	}
	.amendment del, .correction del, .addition del,
	del[class^=c] {
		text-decoration-style: dotted;
	}
	.amendment.proposed ins, .correction.proposed ins, .addition.proposed ins,
	ins[class^=c].proposed {
		text-decoration-style: double;
	}
	.amendment.proposed del, .correction.proposed del, .addition.proposed del,
	del[class^=c].proposed {
		text-decoration-style: double;
	}

/** Miscellaneous improvements to inline formatting ***************************/

	sup {
		vertical-align: super;
		font-size: 80%
	}

/******************************************************************************/
/*                                    Code                                    */
/******************************************************************************/

/** General monospace/pre rules ***********************************************/

	pre, code, samp {
		font-family: Menlo, Consolas, "DejaVu Sans Mono", Monaco, monospace;
		font-size: .9em;
		hyphens: none;
		text-transform: none;
		text-align: left;
		text-align: start;
		font-variant: normal;
		orphans: 3;
		widows: 3;
		page-break-before: avoid;
	}
	pre code,
	code code {
		font-size: 100%;
	}

	pre {
		margin-top: 1em;
		margin-bottom: 1em;
		overflow: auto;
	}

/** Inline Code fragments *****************************************************/

	/* Do something nice. */

/******************************************************************************/
/*                                    Links                                   */
/******************************************************************************/

/** General Hyperlinks ********************************************************/

	/* We hyperlink a lot, so make it less intrusive */
	a[href] {
		color: #034575;
		color: var(--a-normal-text);
		text-decoration: underline #707070;
		text-decoration: underline var(--a-normal-underline);
		text-decoration-skip-ink: none;
	}
	a:visited {
		color: #034575;
		color: var(--a-visited-text);
		text-decoration-color: #bbb;
		text-decoration-color: var(--a-visited-underline);
	}

	/* Indicate interaction with the link */
	a[href]:focus,
	a[href]:hover {
		text-decoration-thickness: 2px;
	}
	a[href]:active {
		color: #c00;
		color: var(--a-active-text);
		text-decoration-color: #c00;
		text-decoration-color: var(--a-active-underline);
	}

	/* Backout above styling for W3C logo */
	.head .logo,
	.head .logo a {
		border: none;
		text-decoration: none;
		background: transparent;
	}

/******************************************************************************/
/*                                    Images                                  */
/******************************************************************************/

	img {
		border-style: none;
	}

	img, svg {
		/* Intentionally not color-scheme aware. */
		background: white;
	}

	/* For autogen numbers, add
	  .caption::before, figcaption::before { content: "Figure " counter(figure) ". "; }
	*/

	figure, .figure, .sidefigure {
		page-break-inside: avoid;
		text-align: center;
		margin: 2.5em 0;
	}
	.figure img,	.sidefigure img,	figure img,
	.figure object, .sidefigure object, figure object {
		max-width: 100%;
		margin: auto;
		height: auto;
	}
	.figure pre, .sidefigure pre, figure pre {
		text-align: left;
		display: table;
		margin: 1em auto;
	}
	.figure table, figure table {
		margin: auto;
	}
	@media screen and (min-width: 20em) {
		.sidefigure {
			float: right;
			width: 50%;
			margin: 0 0 0.5em 0.5em;
		}
	}
	.caption, figcaption, caption {
		font-style: italic;
		font-size: 90%;
	}
	.caption::before, figcaption::before, figcaption > .marker {
		font-weight: bold;
	}
	.caption, figcaption {
		counter-increment: figure;
	}

	/* DL list is indented 2em, but figure inside it is not */
	dd > .figure, dd > figure { margin-left: -2em; }

/******************************************************************************/
/*                             Colored Boxes                                  */
/******************************************************************************/

	.issue, .note, .example, .assertion, .advisement, blockquote,
	.amendment, .correction, .addition {
		margin: 1em auto;
		padding: .5em;
		border: .5em;
		border-left-style: solid;
		page-break-inside: avoid;
	}
	span.issue, span.note {
		padding: .1em .5em .15em;
		border-right-style: solid;
	}

	blockquote > :first-child,
	.note  > p:first-child,
	.issue > p:first-child,
	.amendment > p:first-child,
	.correction > p:first-child,
	.addition > p:first-child {
		margin-top: 0;
	}
	blockquote > :last-child,
	.note  > p:last-child,
	.issue > p:last-child,
	.amendment > p:last-child,
	.correction > p:last-child,
	.addition > p:last-child {
		margin-bottom: 0;
	}


	.issue::before, .issue > .marker,
	.example::before, .example > .marker,
	.note::before, .note > .marker,
	details.note > summary > .marker,
	.amendment::before, .amendment > .marker,
	details.amendment > summary > .marker,
	.addition::before, .addition > .marker,
	addition.amendment > summary > .marker,
	.correction::before, .correction > .marker,
	correction.amendment > summary > .marker
	{
		text-transform: uppercase;
		padding-right: 1em;
	}

	.example::before, .example > .marker {
		display: block;
		padding-right: 0em;
	}

/** Blockquotes ***************************************************************/

	blockquote {
		border-color: silver;
		border-color: var(--blockquote-border);
		background: transparent;
		background: var(--blockquote-bg);
		color: currentcolor;
		color: var(--blockquote-text);
	}

/** Open issue ****************************************************************/

	.issue {
		border-color: #e05252;
		border-color: var(--issue-border);
		background: #fbe9e9;
		background: var(--issue-bg);
		color: black;
		color: var(--issue-text);
		counter-increment: issue;
		overflow: auto;
	}
	.issue::before, .issue > .marker {
		color: #831616;
		color: var(--issueheading-text);
	}
	/* Add .issue::before { content: "Issue " counter(issue) " "; } for autogen numbers,
	  or use class="marker" to mark up the issue number in source. */

/** Example *******************************************************************/

	.example {
		border-color: #e0cb52;
		border-color: var(--example-border);
		background: #fcfaee;
		background: var(--example-bg);
		color: black;
		color: var(--example-text);
		counter-increment: example;
		overflow: auto;
		clear: both;
	}
	.example::before, .example > .marker {
		color: #574b0f;
		color: var(--exampleheading-text);
	}
	/* Add .example::before { content: "Example " counter(example) " "; } for autogen numbers,
	  or use class="marker" to mark up the example number in source. */

/** Non-normative Note ********************************************************/

	.note {
		border-color: #52e052;
		border-color: var(--note-border);
		background: #e9fbe9;
		background: var(--note-bg);
		color: black;
		color: var(--note-text);
		overflow: auto;
	}

	.note::before, .note > .marker,
	details.note > summary {
		color: hsl(120, 70%, 30%);
		color: var(--noteheading-text);
	}
	/* Add .note::before { content: "Note "; } for autogen label,
	  or use class="marker" to mark up the label in source. */

	details.note[open] > summary {
		border-bottom: 1px silver solid;
		border-bottom: 1px var(--notesummary-underline) solid;
	}

/** Assertion Box *************************************************************/
	/*  for assertions in algorithms */

	.assertion {
		border-color: #AAA;
		border-color: var(--assertion-border);
		background: #EEE;
		background: var(--assertion-bg);
		color: black;
		color: var(--assertion-text);
	}

/** Advisement Box ************************************************************/
	/*  for attention-grabbing normative statements */

	.advisement {
		border-color: orange;
		border-color: var(--advisement-border);
		border-style: none solid;
		background: #fec;
		background: var(--advisement-bg);
		color: black;
		color: var(--advisement-text);
	}
	strong.advisement {
		display: block;
		text-align: center;
	}
	.advisement::before, .advisement > .marker {
		color: #b35f00;
		color: var(--advisementheading-text);
	}

/** Amendment Box *************************************************************/

	.amendment, .correction, .addition {
		border-color: #330099;
		border-color: var(--amendment-border);
		background: #F5F0FF;
		background: var(--amendment-bg);
		color: black;
		color: var(--amendment-text);
	}
	.amendment.proposed, .correction.proposed, .addition.proposed {
		border-style: solid;
		border-block-width: 0.25em;
	}
	.amendment::before, .amendment > .marker,
	details.amendment > summary::before, details.amendment > summary > .marker,
	.correction::before, .correction > .marker,
	details.correction > summary::before, details.correction > summary > .marker,
	.addition::before, .addition > .marker,
	details.addition > summary::before, details.addition > summary > .marker {
		color: #220066;
		color: var(--amendmentheading-text);
	}
	.amendment.proposed::before, .amendment.proposed > .marker,
	details.amendment.proposed > summary::before, details.amendment.proposed > summary > .marker,
	.correction.proposed::before, .correction.proposed > .marker,
	details.correction.proposed > summary::before, details.correction.proposed > summary > .marker,
	.addition.proposed::before, .addition.proposed > .marker,
	details.addition.proposed > summary::before, details.addition.proposed > summary > .marker {
		font-weight: bold;
	}

/** Spec Obsoletion Notice ****************************************************/
	/* obnoxious obsoletion notice for older/abandoned specs. */

	details {
		display: block;
	}
	summary {
		font-weight: bolder;
	}

	.annoying-warning:not(details),
	details.annoying-warning:not([open]) > summary,
	details.annoying-warning[open] {
		background: hsla(40,100%,50%,0.95);
		background: var(--warning-bg);
		color: black;
		color: var(--warning-text);
		padding: .75em 1em;
		border: red;
		border: var(--warning-border);
		border-style: solid none;
		box-shadow: 0 2px 8px black;
		text-align: center;
	}
	.annoying-warning :last-child {
		margin-bottom: 0;
	}

@media not print {
	details.annoying-warning[open] {
		position: fixed;
		left: 0;
		right: 0;
		bottom: 2em;
		z-index: 1000;
	}
}

	details.annoying-warning:not([open]) > summary {
		text-align: center;
	}

/** Entity Definition Boxes ***************************************************/

	.def {
		padding: .5em 1em;
		background: #def;
		background: var(--def-bg);
		margin: 1.2em 0;
		border-left: 0.5em solid #8ccbf2;
		border-left: 0.5em solid var(--def-border);
		color: black;
		color: var(--def-text);
	}

/******************************************************************************/
/*                                    Tables                                  */
/******************************************************************************/

	th, td {
		text-align: left;
		text-align: start;
	}

/** Property/Descriptor Definition Tables *************************************/

	table.def {
		/* inherits .def box styling, see above */
		width: 100%;
		border-spacing: 0;
	}

	table.def td,
	table.def th {
		padding: 0.5em;
		vertical-align: baseline;
		border-bottom: 1px solid #bbd7e9;
		border-bottom: 1px solid var(--defrow-border);
	}

	table.def > tbody > tr:last-child th,
	table.def > tbody > tr:last-child td {
		border-bottom: 0;
	}

	table.def th {
		font-style: italic;
		font-weight: normal;
		padding-left: 1em;
		width: 3em;
	}

	/* For when values are extra-complex and need formatting for readability */
	table td.pre {
		white-space: pre-wrap;
	}

	/* A footnote at the bottom of a def table */
	table.def td.footnote {
		padding-top: 0.6em;
	}
	table.def td.footnote::before {
		content: " ";
		display: block;
		height: 0.6em;
		width: 4em;
		border-top: thin solid;
	}

/** Data tables (and properly marked-up index tables) *************************/
	/*
		<table class="data"> highlights structural relationships in a table
		when correct markup is used (e.g. thead/tbody, th vs. td, scope attribute)

		Use class="complex data" for particularly complicated tables --
		(This will draw more lines: busier, but clearer.)

		Use class="long" on table cells with paragraph-like contents
		(This will adjust text alignment accordingly.)
		Alternately use class="longlastcol" on tables, to have the last column assume "long".
	*/

	table {
		word-wrap: normal;
		overflow-wrap: normal;
		hyphens: manual;
	}

	table.data,
	table.index {
		margin: 1em auto;
		border-collapse: collapse;
		border: hidden;
		width: 100%;
	}
	table.data caption,
	table.index caption {
		max-width: 50em;
		margin: 0 auto 1em;
	}

	table.data td,  table.data th,
	table.index td, table.index th {
		padding: 0.5em 1em;
		border-width: 1px;
		border-color: silver;
		border-color: var(--datacell-border);
		border-top-style: solid;
	}

	table.data thead td:empty {
		padding: 0;
		border: 0;
	}

	table.data  thead,
	table.index thead,
	table.data  tbody,
	table.index tbody {
		border-bottom: 2px solid;
	}

	table.data colgroup,
	table.index colgroup {
		border-left: 2px solid;
	}

	table.data  tbody th:first-child,
	table.index tbody th:first-child  {
		border-right: 2px solid;
		border-top: 1px solid silver;
		border-top: 1px solid var(--datacell-border);
		padding-right: 1em;
	}

	table.data th[colspan],
	table.data td[colspan] {
		text-align: center;
	}

	table.complex.data th,
	table.complex.data td {
		border: 1px solid silver;
		border: 1px solid var(--datacell-border);
		text-align: center;
	}

	table.data.longlastcol td:last-child,
	table.data td.long {
		vertical-align: baseline;
		text-align: left;
	}

	table.data img {
		vertical-align: middle;
	}


/*
Alternate table alignment rules

	table.data,
	table.index {
		text-align: center;
	}

	table.data  thead th[scope="row"],
	table.index thead th[scope="row"] {
		text-align: right;
	}

	table.data  tbody th:first-child,
	table.index tbody th:first-child  {
		text-align: right;
	}

Possible extra rowspan handling

	table.data  tbody th[rowspan]:not([rowspan='1']),
	table.index tbody th[rowspan]:not([rowspan='1']),
	table.data  tbody td[rowspan]:not([rowspan='1']),
	table.index tbody td[rowspan]:not([rowspan='1']) {
		border-left: 1px solid silver;
	}

	table.data  tbody th[rowspan]:first-child,
	table.index tbody th[rowspan]:first-child,
	table.data  tbody td[rowspan]:first-child,
	table.index tbody td[rowspan]:first-child{
		border-left: 0;
		border-right: 1px solid silver;
	}
*/

/******************************************************************************/
/*                                  Indices                                   */
/******************************************************************************/


/** Table of Contents *********************************************************/

	.toc a {
		/* More spacing; use padding to make it part of the click target. */
		padding: 0.1rem 1px 0;
		/* Larger, more consistently-sized click target */
		display: block;
		/* Switch to using border-bottom for underlines */
		text-decoration: none;
		border-bottom: 1px solid;
		/* Reverse color scheme */
		color: black;
		color: var(--toclink-text);
		border-color: #3980b5;
		border-color: var(--toclink-underline);
	}
	.toc a:visited {
		color: black;
		color: var(--toclink-visited-text);
		border-color: #054572;
		border-color: var(--toclink-visited-underline);
	}
	.toc a:focus,
	.toc a:hover {
		background: rgba(75%, 75%, 75%, .25);
		background: var(--a-hover-bg);
		border-bottom-width: 3px;
		margin-bottom: -2px;
	}
	.toc a:not(:focus):not(:hover) {
		/* Allow colors to cascade through from link styling */
		border-bottom-color: transparent;
	}

	.toc, .toc ol, .toc ul, .toc li {
		list-style: none; /* Numbers must be inlined into source */
		/* because generated content isn't search/selectable and markers can't do multilevel yet */
		margin:  0;
		padding: 0;
	}
	.toc {
		line-height: 1.1em;
	}

	/* ToC not indented until third level, but font style & margins show hierarchy */
	.toc > li			{ font-weight: bold;   }
	.toc > li li		 { font-weight: normal; }
	.toc > li li li	  { font-size:   95%;	}
	.toc > li li li li	{ font-size:   90%;	}
	.toc > li li li li li { font-size:   85%;	}

	/* @supports not (display:grid) { */
		.toc > li			{ margin: 1.5rem 0;	}
		.toc > li li		 { margin: 0.3rem 0;	}
		.toc > li li li	  { margin-left: 2rem;   }

		/* Section numbers in a column of their own */
		.toc .secno {
			float: left;
			width: 4rem;
			white-space: nowrap;
		}
		.toc > li li li li .secno { font-size: 85%; }
		.toc > li li li li li .secno { font-size: 100%; }

		.toc li {
			clear: both;
		}

		:not(li) > .toc			 { margin-left:  5rem; }
		.toc .secno				 { margin-left: -5rem; }
		.toc > li li li .secno	  { margin-left: -7rem; }
		.toc > li li li li .secno	{ margin-left: -9rem; }
		.toc > li li li li li .secno { margin-left: -11rem; }

		/* Tighten up indentation in narrow ToCs */
		@media (max-width: 30em) {
			:not(li) > .toc			 { margin-left:  4rem; }
			.toc .secno				 { margin-left: -4rem; }
			.toc > li li li			 { margin-left:  1rem; }
			.toc > li li li .secno	  { margin-left: -5rem; }
			.toc > li li li li .secno	{ margin-left: -6rem; }
			.toc > li li li li li .secno { margin-left: -7rem; }
		}
		/* Loosen it on wide screens */
		@media screen and (min-width: 78em) {
			body:not(.toc-inline) :not(li) > .toc			 { margin-left:  4rem; }
			body:not(.toc-inline) .toc .secno				 { margin-left: -4rem; }
			body:not(.toc-inline) .toc > li li li			 { margin-left:  1rem; }
			body:not(.toc-inline) .toc > li li li .secno	  { margin-left: -5rem; }
			body:not(.toc-inline) .toc > li li li li .secno	{ margin-left: -6rem; }
			body:not(.toc-inline) .toc > li li li li li .secno { margin-left: -7rem; }
	}
	/* } */

	@supports (display:grid) and (display:contents) {
		/* Use #toc over .toc to override non-@supports rules. */
		#toc {
			display: grid;
			align-content: start;
			grid-template-columns: auto 1fr;
			grid-column-gap: 1rem;
			column-gap: 1rem;
			grid-row-gap: .6rem;
			row-gap: .6rem;
		}
		#toc h2 {
			grid-column: 1 / -1;
			margin-bottom: 0;
		}
		#toc ol,
		#toc li,
		#toc a {
			display: contents;
			/* Switch <a> to subgrid when supported */
		}
		#toc span {
			margin: 0;
		}
		#toc > .toc > li > a > span {
			/* The spans of the top-level list,
			  comprising the first items of each top-level section. */
			margin-top: 1.1rem;
		}
		#toc#toc .secno { /* Ugh, need more specificity to override base.css */
			grid-column: 1;
			width: auto;
			margin-left: 0;
		}
		#toc .content {
			grid-column: 2;
			width: auto;
			margin-right: 1rem;
			border-bottom: 3px solid transparent;
			margin-bottom: -3px;
		}
		#toc .content:hover,
		#toc .content:focus {
			background: rgba(75%, 75%, 75%, .25);
			background: var(--a-hover-bg);
			border-bottom-color: #054572;
			border-bottom-color: var(--toclink-underline);
		}
		#toc li li li .content {
			margin-left: 1rem;
		}
		#toc li li li li .content {
			margin-left: 2rem;
		}
	}


/** Index *********************************************************************/

	/* Index Lists: Layout */
	ul.index	  { margin-left: 0; columns: 15em; text-indent: 1em hanging; }
	ul.index li	{ margin-left: 0; list-style: none; break-inside: avoid; }
	ul.index li li { margin-left: 1em; }
	ul.index dl	{ margin-top: 0; }
	ul.index dt	{ margin: .2em 0 .2em 20px;}
	ul.index dd	{ margin: .2em 0 .2em 40px;}
	/* Index Lists: Typography */
	ul.index ul,
	ul.index dl { font-size: smaller; }
	@media not print {
		ul.index li a + span {
			white-space: nowrap;
			color: transparent; }
		ul.index li a:hover + span,
		ul.index li a:focus + span {
			color: #707070;
			color: var(--indexinfo-text);
		}
	}

/** Index Tables *****************************************************/
	/* See also the data table styling section, which this effectively subclasses */

	table.index {
		font-size: small;
		border-collapse: collapse;
		border-spacing: 0;
		text-align: left;
		margin: 1em 0;
	}

	table.index td,
	table.index th {
		padding: 0.4em;
	}

	table.index tr:hover td:not([rowspan]),
	table.index tr:hover th:not([rowspan]) {
		color: black;
		color: var(--indextable-hover-text);
		background: #f7f8f9;
		background: var(--indextable-hover-bg);
	}

	/* The link in the first column in the property table (formerly a TD) */
	table.index th:first-child a {
		font-weight: bold;
	}

/** Outdated warning **********************************************************/

.outdated-spec {
	color: black;
	color: var(--outdatedspec-text);
	background-color: rgba(0,0,0,0.5);
	background-color: var(--outdatedspec-bg);
}

.outdated-warning {
	position: fixed;
	bottom: 50%;
	left: 0;
	right: 0;
	margin: 0 auto;
	width: 50%;
	background: maroon;
	background: var(--outdated-bg);
	color: white;
	color: var(--outdated-text);
	border-radius: 1em;
	box-shadow: 0 0 1em red;
	box-shadow: 0 0 1em var(--outdated-shadow);
	padding: 2em;
	text-align: center;
	z-index: 2;
}

.outdated-warning a {
	color: currentcolor;
	background: transparent;
}

.edited-rec-warning {
	background: darkorange;
	background: var(--editedrec-bg);
	box-shadow: 0 0 1em;
}

.outdated-warning button {
	color: var(--outdated-text);
	border-radius: 1em;
	box-shadow: 0 0 1em red;
	box-shadow: 0 0 1em var(--outdated-shadow);
	padding: 2em;
	text-align: center;
	z-index: 2;
}

.outdated-warning a {
	color: currentcolor;
	background: transparent;
}

.edited-rec-warning {
	background: darkorange;
	background: var(--editedrec-bg);
	box-shadow: 0 0 1em;
}

.outdated-warning button {
	position: absolute;
	top: 0;
	right:0;
	margin: 0;
	border: 0;
	padding: 0.25em 0.5em;
	background: transparent;
	color: white;
	color: var(--outdated-text);
	font:1em sans-serif;
	text-align:center;
}

.outdated-warning span {
	display: block;
}

.outdated-collapsed {
	bottom: 0;
	border-radius: 0;
	width: 100%;
	padding: 0;
}

/******************************************************************************/
/*                                    Print                                   */
/******************************************************************************/

	@media print {
		/* Pages have their own margins. */
		html {
			margin: 0;
		}
		/* Serif for print. */
		body {
			font-family: serif;
		}

		.outdated-warning {
			position: absolute;
			border-style: solid;
			border-color: red;
		}

		.outdated-warning input {
			display: none;
		}
	}
	@page {
		margin: 1.5cm 1.1cm;
	}



/******************************************************************************/
/*                             Overflow Control                               */
/******************************************************************************/

	.figure .caption, .sidefigure .caption, figcaption {
		/* in case figure is overlarge, limit caption to 50em */
		max-width: 50rem;
		margin-left: auto;
		margin-right: auto;
	}
	.overlarge {
		/* Magic to create good item positioning:
		  "content column" is 50ems wide at max; less on smaller screens.
		  Extra space (after ToC + content) is empty on the right.

		  1. When item < content column, centers item in column.
		  2. When content < item < available, left-aligns.
		  3. When item > available, fills available + scroll bar.
		*/
		display: grid;
		grid-template-columns: minmax(0, 50em);
	}
	.overlarge > table {
		/* limit preferred width of table */
		max-width: 50em;
		margin-left: auto;
		margin-right: auto;
	}

	@media (min-width: 55em) {
		.overlarge {
			margin-right: calc(13px + 26.5rem - 50vw);
			max-width: none;
		}
	}
	@media screen and (min-width: 78em) {
		body:not(.toc-inline) .overlarge {
			/* 30.5em body padding 50em content area */
			margin-right: calc(40em - 50vw) !important;
		}
	}
	@media screen and (min-width: 90em) {
		body:not(.toc-inline) .overlarge {
			/* 4em html margin 30.5em body padding 50em content area */
			margin-right: calc(84.5em - 100vw) !important;
		}
	}

	@media not print {
		.overlarge {
			overflow-x: auto;
			/* See Lea Verou's explanation background-attachment:
			* http://lea.verou.me/2012/04/background-attachment-local/
			*
			background: top left  / 4em 100% linear-gradient(to right,  #ffffff, rgba(255, 255, 255, 0)) local,
						top right / 4em 100% linear-gradient(to left, #ffffff, rgba(255, 255, 255, 0)) local,
						top left  / 1em 100% linear-gradient(to right,  #c3c3c5, rgba(195, 195, 197, 0)) scroll,
						top right / 1em 100% linear-gradient(to left, #c3c3c5, rgba(195, 195, 197, 0)) scroll,
						white;
			background-repeat: no-repeat;
			*/
		}
	}
</style>
<style>
    table, th, td {
      border: 1px solid black;
      border-collapse: collapse;
      vertical-align: top;
    }
    th, td {
      border-left: none;
      border-right: none;
      padding: 0px 10px;
    }
    th {
      text-align: center;
    }

    del { background: #fcc; color: #000; text-decoration: line-through; }
    ins { background: #cfc; color: #000; }
    blockquote .highlight:not(.idl) { background: initial; margin: initial; padding: 0.5em }
    blockquote ul { background: inherit; }
    blockquote code.highlight:not(.idl) { padding: initial; }
    blockquote c-[a] { color: inherit; } /* Keyword.Declaration */
    blockquote c-[b] { color: inherit; } /* Keyword.Type */
    blockquote c-[c] { color: inherit; } /* Comment */
    blockquote c-[d] { color: inherit; } /* Comment.Multiline */
    blockquote c-[e] { color: inherit; } /* Name.Attribute */
    blockquote c-[f] { color: inherit; } /* Name.Tag */
    blockquote c-[g] { color: inherit; } /* Name.Variable */
    blockquote c-[k] { color: inherit; } /* Keyword */
    blockquote c-[l] { color: inherit; } /* Literal */
    blockquote c-[m] { color: inherit; } /* Literal.Number */
    blockquote c-[n] { color: inherit; } /* Name */
    blockquote c-[o] { color: inherit; } /* Operator */
    blockquote c-[p] { color: inherit; } /* Punctuation */
    blockquote c-[s] { color: inherit; } /* Literal.String */
    blockquote c-[t] { color: inherit; } /* Literal.String.Single */
    blockquote c-[u] { color: inherit; } /* Literal.String.Double */
    blockquote c-[cp] { color: inherit; } /* Comment.Preproc */
    blockquote c-[c1] { color: inherit; } /* Comment.Single */
    blockquote c-[cs] { color: inherit; } /* Comment.Special */
    blockquote c-[kc] { color: inherit; } /* Keyword.Constant */
    blockquote c-[kn] { color: inherit; } /* Keyword.Namespace */
    blockquote c-[kp] { color: inherit; } /* Keyword.Pseudo */
    blockquote c-[kr] { color: inherit; } /* Keyword.Reserved */
    blockquote c-[ld] { color: inherit; } /* Literal.Date */
    blockquote c-[nc] { color: inherit; } /* Name.Class */
    blockquote c-[no] { color: inherit; } /* Name.Constant */
    blockquote c-[nd] { color: inherit; } /* Name.Decorator */
    blockquote c-[ni] { color: inherit; } /* Name.Entity */
    blockquote c-[ne] { color: inherit; } /* Name.Exception */
    blockquote c-[nf] { color: inherit; } /* Name.Function */
    blockquote c-[nl] { color: inherit; } /* Name.Label */
    blockquote c-[nn] { color: inherit; } /* Name.Namespace */
    blockquote c-[py] { color: inherit; } /* Name.Property */
    blockquote c-[ow] { color: inherit; } /* Operator.Word */
    blockquote c-[mb] { color: inherit; } /* Literal.Number.Bin */
    blockquote c-[mf] { color: inherit; } /* Literal.Number.Float */
    blockquote c-[mh] { color: inherit; } /* Literal.Number.Hex */
    blockquote c-[mi] { color: inherit; } /* Literal.Number.Integer */
    blockquote c-[mo] { color: inherit; } /* Literal.Number.Oct */
    blockquote c-[sb] { color: inherit; } /* Literal.String.Backtick */
    blockquote c-[sc] { color: inherit; } /* Literal.String.Char */
    blockquote c-[sd] { color: inherit; } /* Literal.String.Doc */
    blockquote c-[se] { color: inherit; } /* Literal.String.Escape */
    blockquote c-[sh] { color: inherit; } /* Literal.String.Heredoc */
    blockquote c-[si] { color: inherit; } /* Literal.String.Interpol */
    blockquote c-[sx] { color: inherit; } /* Literal.String.Other */
    blockquote c-[sr] { color: inherit; } /* Literal.String.Regex */
    blockquote c-[ss] { color: inherit; } /* Literal.String.Symbol */
    blockquote c-[vc] { color: inherit; } /* Name.Variable.Class */
    blockquote c-[vg] { color: inherit; } /* Name.Variable.Global */
    blockquote c-[vi] { color: inherit; } /* Name.Variable.Instance */
    blockquote c-[il] { color: inherit; } /* Literal.Number.Integer.Long */
  </style>
  <meta content="Bikeshed version d765c696b, updated Fri Mar 8 15:58:52 2024 -0800" name="generator">
  <link href="https://wg21.link/P3085" rel="canonical">
  <link href="https://isocpp.org/favicon.ico" rel="icon">
  <meta content="dark light" name="color-scheme">
<style>/* Boilerplate: style-autolinks */
.css.css, .property.property, .descriptor.descriptor {
    color: var(--a-normal-text);
    font-size: inherit;
    font-family: inherit;
}
.css::before, .property::before, .descriptor::before {
    content: "‘";
}
.css::after, .property::after, .descriptor::after {
    content: "’";
}
.property, .descriptor {
    /* Don't wrap property and descriptor names */
    white-space: nowrap;
}
.type { /* CSS value <type> */
    font-style: italic;
}
pre .property::before, pre .property::after {
    content: "";
}
[data-link-type="property"]::before,
[data-link-type="propdesc"]::before,
[data-link-type="descriptor"]::before,
[data-link-type="value"]::before,
[data-link-type="function"]::before,
[data-link-type="at-rule"]::before,
[data-link-type="selector"]::before,
[data-link-type="maybe"]::before {
    content: "‘";
}
[data-link-type="property"]::after,
[data-link-type="propdesc"]::after,
[data-link-type="descriptor"]::after,
[data-link-type="value"]::after,
[data-link-type="function"]::after,
[data-link-type="at-rule"]::after,
[data-link-type="selector"]::after,
[data-link-type="maybe"]::after {
    content: "’";
}

[data-link-type].production::before,
[data-link-type].production::after,
.prod [data-link-type]::before,
.prod [data-link-type]::after {
    content: "";
}

[data-link-type=element],
[data-link-type=element-attr] {
    font-family: Menlo, Consolas, "DejaVu Sans Mono", monospace;
    font-size: .9em;
}
[data-link-type=element]::before { content: "<" }
[data-link-type=element]::after  { content: ">" }

[data-link-type=biblio] {
    white-space: pre;
}

@media (prefers-color-scheme: dark) {
    :root {
        --selflink-text: black;
        --selflink-bg: silver;
        --selflink-hover-text: white;
    }
}
</style>
<style>/* Boilerplate: style-colors */
/* Any --*-text not paired with a --*-bg is assumed to have a transparent bg */
:root {
    color-scheme: light dark;

    --text: black;
    --bg: white;

    --unofficial-watermark: url(https://www.w3.org/StyleSheets/TR/2016/logos/UD-watermark);

    --logo-bg: #1a5e9a;
    --logo-active-bg: #c00;
    --logo-text: white;

    --tocnav-normal-text: #707070;
    --tocnav-normal-bg: var(--bg);
    --tocnav-hover-text: var(--tocnav-normal-text);
    --tocnav-hover-bg: #f8f8f8;
    --tocnav-active-text: #c00;
    --tocnav-active-bg: var(--tocnav-normal-bg);

    --tocsidebar-text: var(--text);
    --tocsidebar-bg: #f7f8f9;
    --tocsidebar-shadow: rgba(0,0,0,.1);
    --tocsidebar-heading-text: hsla(203,20%,40%,.7);

    --toclink-text: var(--text);
    --toclink-underline: #3980b5;
    --toclink-visited-text: var(--toclink-text);
    --toclink-visited-underline: #054572;

    --heading-text: #005a9c;

    --hr-text: var(--text);

    --algo-border: #def;

    --del-text: red;
    --del-bg: transparent;
    --ins-text: #080;
    --ins-bg: transparent;

    --a-normal-text: #034575;
    --a-normal-underline: #bbb;
    --a-visited-text: var(--a-normal-text);
    --a-visited-underline: #707070;
    --a-hover-bg: rgba(75%, 75%, 75%, .25);
    --a-active-text: #c00;
    --a-active-underline: #c00;

    --blockquote-border: silver;
    --blockquote-bg: transparent;
    --blockquote-text: currentcolor;

    --issue-border: #e05252;
    --issue-bg: #fbe9e9;
    --issue-text: var(--text);
    --issueheading-text: #831616;

    --example-border: #e0cb52;
    --example-bg: #fcfaee;
    --example-text: var(--text);
    --exampleheading-text: #574b0f;

    --note-border: #52e052;
    --note-bg: #e9fbe9;
    --note-text: var(--text);
    --noteheading-text: hsl(120, 70%, 30%);
    --notesummary-underline: silver;

    --assertion-border: #aaa;
    --assertion-bg: #eee;
    --assertion-text: black;

    --advisement-border: orange;
    --advisement-bg: #fec;
    --advisement-text: var(--text);
    --advisementheading-text: #b35f00;

    --warning-border: red;
    --warning-bg: hsla(40,100%,50%,0.95);
    --warning-text: var(--text);

    --amendment-border: #330099;
    --amendment-bg: #F5F0FF;
    --amendment-text: var(--text);
    --amendmentheading-text: #220066;

    --def-border: #8ccbf2;
    --def-bg: #def;
    --def-text: var(--text);
    --defrow-border: #bbd7e9;

    --datacell-border: silver;

    --indexinfo-text: #707070;

    --indextable-hover-text: black;
    --indextable-hover-bg: #f7f8f9;

    --outdatedspec-bg: rgba(0, 0, 0, .5);
    --outdatedspec-text: black;
    --outdated-bg: maroon;
    --outdated-text: white;
    --outdated-shadow: red;

    --editedrec-bg: darkorange;
}

@media (prefers-color-scheme: dark) {
    :root {
        --text: #ddd;
        --bg: black;

        --unofficial-watermark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='400'%3E%3Cg fill='%23100808' transform='translate(200 200) rotate(-45) translate(-200 -200)' stroke='%23100808' stroke-width='3'%3E%3Ctext x='50%25' y='220' style='font: bold 70px sans-serif; text-anchor: middle; letter-spacing: 6px;'%3EUNOFFICIAL%3C/text%3E%3Ctext x='50%25' y='305' style='font: bold 70px sans-serif; text-anchor: middle; letter-spacing: 6px;'%3EDRAFT%3C/text%3E%3C/g%3E%3C/svg%3E");

        --logo-bg: #1a5e9a;
        --logo-active-bg: #c00;
        --logo-text: white;

        --tocnav-normal-text: #999;
        --tocnav-normal-bg: var(--bg);
        --tocnav-hover-text: var(--tocnav-normal-text);
        --tocnav-hover-bg: #080808;
        --tocnav-active-text: #f44;
        --tocnav-active-bg: var(--tocnav-normal-bg);

        --tocsidebar-text: var(--text);
        --tocsidebar-bg: #080808;
        --tocsidebar-shadow: rgba(255,255,255,.1);
        --tocsidebar-heading-text: hsla(203,20%,40%,.7);

        --toclink-text: var(--text);
        --toclink-underline: #6af;
        --toclink-visited-text: var(--toclink-text);
        --toclink-visited-underline: #054572;

        --heading-text: #8af;

        --hr-text: var(--text);

        --algo-border: #456;

        --del-text: #f44;
        --del-bg: transparent;
        --ins-text: #4a4;
        --ins-bg: transparent;

        --a-normal-text: #6af;
        --a-normal-underline: #555;
        --a-visited-text: var(--a-normal-text);
        --a-visited-underline: var(--a-normal-underline);
        --a-hover-bg: rgba(25%, 25%, 25%, .2);
        --a-active-text: #f44;
        --a-active-underline: var(--a-active-text);

        --borderedblock-bg: rgba(255, 255, 255, .05);

        --blockquote-border: silver;
        --blockquote-bg: var(--borderedblock-bg);
        --blockquote-text: currentcolor;

        --issue-border: #e05252;
        --issue-bg: var(--borderedblock-bg);
        --issue-text: var(--text);
        --issueheading-text: hsl(0deg, 70%, 70%);

        --example-border: hsl(50deg, 90%, 60%);
        --example-bg: var(--borderedblock-bg);
        --example-text: var(--text);
        --exampleheading-text: hsl(50deg, 70%, 70%);

        --note-border: hsl(120deg, 100%, 35%);
        --note-bg: var(--borderedblock-bg);
        --note-text: var(--text);
        --noteheading-text: hsl(120, 70%, 70%);
        --notesummary-underline: silver;

        --assertion-border: #444;
        --assertion-bg: var(--borderedblock-bg);
        --assertion-text: var(--text);

        --advisement-border: orange;
        --advisement-bg: #222218;
        --advisement-text: var(--text);
        --advisementheading-text: #f84;

        --warning-border: red;
        --warning-bg: hsla(40,100%,20%,0.95);
        --warning-text: var(--text);

        --amendment-border: #330099;
        --amendment-bg: #080010;
        --amendment-text: var(--text);
        --amendmentheading-text: #cc00ff;

        --def-border: #8ccbf2;
        --def-bg: #080818;
        --def-text: var(--text);
        --defrow-border: #136;

        --datacell-border: silver;

        --indexinfo-text: #aaa;

        --indextable-hover-text: var(--text);
        --indextable-hover-bg: #181818;

        --outdatedspec-bg: rgba(255, 255, 255, .5);
        --outdatedspec-text: black;
        --outdated-bg: maroon;
        --outdated-text: white;
        --outdated-shadow: red;

        --editedrec-bg: darkorange;
    }
    /* In case a transparent-bg image doesn't expect to be on a dark bg,
       which is quite common in practice... */
    img { background: white; }
}
</style>
<style>/* Boilerplate: style-counters */
body {
    counter-reset: example figure issue;
}
.issue {
    counter-increment: issue;
}
.issue:not(.no-marker)::before {
    content: "Issue " counter(issue);
}

.example {
    counter-increment: example;
}
.example:not(.no-marker)::before {
    content: "Example " counter(example);
}
.invalid.example:not(.no-marker)::before,
.illegal.example:not(.no-marker)::before {
    content: "Invalid Example" counter(example);
}

figcaption {
    counter-increment: figure;
}
figcaption:not(.no-marker)::before {
    content: "Figure " counter(figure) " ";
}
</style>
<style>/* Boilerplate: style-issues */
a[href].issue-return {
    float: right;
    float: inline-end;
    color: var(--issueheading-text);
    font-weight: bold;
    text-decoration: none;
}
</style>
<style>/* Boilerplate: style-md-lists */
/* This is a weird hack for me not yet following the commonmark spec
   regarding paragraph and lists. */
[data-md] > :first-child {
    margin-top: 0;
}
[data-md] > :last-child {
    margin-bottom: 0;
}
</style>
<style>/* Boilerplate: style-selflinks */
:root {
    --selflink-text: white;
    --selflink-bg: gray;
    --selflink-hover-text: black;
}
.heading, .issue, .note, .example, li, dt {
    position: relative;
}
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;
}
a.self-link:hover {
    opacity: 1;
}
.heading > a.self-link {
    font-size: 83%;
}
.example > a.self-link,
.note > a.self-link,
.issue > a.self-link {
    /* These blocks are overflow:auto, so positioning outside
       doesn't work. */
    left: auto;
    right: 0;
}
li > a.self-link {
    left: calc(-1 * (3.5rem - 26px) - 2em);
}
dfn > a.self-link {
    top: auto;
    left: auto;
    opacity: 0;
    width: 1.5em;
    height: 1.5em;
    background: var(--selflink-bg);
    color: var(--selflink-text);
    font-style: normal;
    transition: opacity .2s, background-color .2s, color .2s;
}
dfn:hover > a.self-link {
    opacity: 1;
}
dfn > a.self-link:hover {
    color: var(--selflink-hover-text);
}

a.self-link::before            { content: "¶"; }
.heading > a.self-link::before { content: "§"; }
dfn > a.self-link::before      { content: "#"; }
</style>
<style>/* Boilerplate: style-syntax-highlighting */
code.highlight { padding: .1em; border-radius: .3em; }
pre.highlight, pre > code.highlight { display: block; padding: 1em; margin: .5em 0; overflow: auto; border-radius: 0; }

.highlight:not(.idl) { background: rgba(0, 0, 0, .03); }
c-[a] { color: #990055 } /* Keyword.Declaration */
c-[b] { color: #990055 } /* Keyword.Type */
c-[c] { color: #708090 } /* Comment */
c-[d] { color: #708090 } /* Comment.Multiline */
c-[e] { color: #0077aa } /* Name.Attribute */
c-[f] { color: #669900 } /* Name.Tag */
c-[g] { color: #222222 } /* Name.Variable */
c-[k] { color: #990055 } /* Keyword */
c-[l] { color: #000000 } /* Literal */
c-[m] { color: #000000 } /* Literal.Number */
c-[n] { color: #0077aa } /* Name */
c-[o] { color: #999999 } /* Operator */
c-[p] { color: #999999 } /* Punctuation */
c-[s] { color: #a67f59 } /* Literal.String */
c-[t] { color: #a67f59 } /* Literal.String.Single */
c-[u] { color: #a67f59 } /* Literal.String.Double */
c-[cp] { color: #708090 } /* Comment.Preproc */
c-[c1] { color: #708090 } /* Comment.Single */
c-[cs] { color: #708090 } /* Comment.Special */
c-[kc] { color: #990055 } /* Keyword.Constant */
c-[kn] { color: #990055 } /* Keyword.Namespace */
c-[kp] { color: #990055 } /* Keyword.Pseudo */
c-[kr] { color: #990055 } /* Keyword.Reserved */
c-[ld] { color: #000000 } /* Literal.Date */
c-[nc] { color: #0077aa } /* Name.Class */
c-[no] { color: #0077aa } /* Name.Constant */
c-[nd] { color: #0077aa } /* Name.Decorator */
c-[ni] { color: #0077aa } /* Name.Entity */
c-[ne] { color: #0077aa } /* Name.Exception */
c-[nf] { color: #0077aa } /* Name.Function */
c-[nl] { color: #0077aa } /* Name.Label */
c-[nn] { color: #0077aa } /* Name.Namespace */
c-[py] { color: #0077aa } /* Name.Property */
c-[ow] { color: #999999 } /* Operator.Word */
c-[mb] { color: #000000 } /* Literal.Number.Bin */
c-[mf] { color: #000000 } /* Literal.Number.Float */
c-[mh] { color: #000000 } /* Literal.Number.Hex */
c-[mi] { color: #000000 } /* Literal.Number.Integer */
c-[mo] { color: #000000 } /* Literal.Number.Oct */
c-[sb] { color: #a67f59 } /* Literal.String.Backtick */
c-[sc] { color: #a67f59 } /* Literal.String.Char */
c-[sd] { color: #a67f59 } /* Literal.String.Doc */
c-[se] { color: #a67f59 } /* Literal.String.Escape */
c-[sh] { color: #a67f59 } /* Literal.String.Heredoc */
c-[si] { color: #a67f59 } /* Literal.String.Interpol */
c-[sx] { color: #a67f59 } /* Literal.String.Other */
c-[sr] { color: #a67f59 } /* Literal.String.Regex */
c-[ss] { color: #a67f59 } /* Literal.String.Symbol */
c-[vc] { color: #0077aa } /* Name.Variable.Class */
c-[vg] { color: #0077aa } /* Name.Variable.Global */
c-[vi] { color: #0077aa } /* Name.Variable.Instance */
c-[il] { color: #000000 } /* Literal.Number.Integer.Long */

@media (prefers-color-scheme: dark) {
    .highlight:not(.idl) { background: rgba(255, 255, 255, .05); }

    c-[a] { color: #d33682 } /* Keyword.Declaration */
    c-[b] { color: #d33682 } /* Keyword.Type */
    c-[c] { color: #2aa198 } /* Comment */
    c-[d] { color: #2aa198 } /* Comment.Multiline */
    c-[e] { color: #268bd2 } /* Name.Attribute */
    c-[f] { color: #b58900 } /* Name.Tag */
    c-[g] { color: #cb4b16 } /* Name.Variable */
    c-[k] { color: #d33682 } /* Keyword */
    c-[l] { color: #657b83 } /* Literal */
    c-[m] { color: #657b83 } /* Literal.Number */
    c-[n] { color: #268bd2 } /* Name */
    c-[o] { color: #657b83 } /* Operator */
    c-[p] { color: #657b83 } /* Punctuation */
    c-[s] { color: #6c71c4 } /* Literal.String */
    c-[t] { color: #6c71c4 } /* Literal.String.Single */
    c-[u] { color: #6c71c4 } /* Literal.String.Double */
    c-[ch] { color: #2aa198 } /* Comment.Hashbang */
    c-[cp] { color: #2aa198 } /* Comment.Preproc */
    c-[cpf] { color: #2aa198 } /* Comment.PreprocFile */
    c-[c1] { color: #2aa198 } /* Comment.Single */
    c-[cs] { color: #2aa198 } /* Comment.Special */
    c-[kc] { color: #d33682 } /* Keyword.Constant */
    c-[kn] { color: #d33682 } /* Keyword.Namespace */
    c-[kp] { color: #d33682 } /* Keyword.Pseudo */
    c-[kr] { color: #d33682 } /* Keyword.Reserved */
    c-[ld] { color: #657b83 } /* Literal.Date */
    c-[nc] { color: #268bd2 } /* Name.Class */
    c-[no] { color: #268bd2 } /* Name.Constant */
    c-[nd] { color: #268bd2 } /* Name.Decorator */
    c-[ni] { color: #268bd2 } /* Name.Entity */
    c-[ne] { color: #268bd2 } /* Name.Exception */
    c-[nf] { color: #268bd2 } /* Name.Function */
    c-[nl] { color: #268bd2 } /* Name.Label */
    c-[nn] { color: #268bd2 } /* Name.Namespace */
    c-[py] { color: #268bd2 } /* Name.Property */
    c-[ow] { color: #657b83 } /* Operator.Word */
    c-[mb] { color: #657b83 } /* Literal.Number.Bin */
    c-[mf] { color: #657b83 } /* Literal.Number.Float */
    c-[mh] { color: #657b83 } /* Literal.Number.Hex */
    c-[mi] { color: #657b83 } /* Literal.Number.Integer */
    c-[mo] { color: #657b83 } /* Literal.Number.Oct */
    c-[sa] { color: #6c71c4 } /* Literal.String.Affix */
    c-[sb] { color: #6c71c4 } /* Literal.String.Backtick */
    c-[sc] { color: #6c71c4 } /* Literal.String.Char */
    c-[dl] { color: #6c71c4 } /* Literal.String.Delimiter */
    c-[sd] { color: #6c71c4 } /* Literal.String.Doc */
    c-[se] { color: #6c71c4 } /* Literal.String.Escape */
    c-[sh] { color: #6c71c4 } /* Literal.String.Heredoc */
    c-[si] { color: #6c71c4 } /* Literal.String.Interpol */
    c-[sx] { color: #6c71c4 } /* Literal.String.Other */
    c-[sr] { color: #6c71c4 } /* Literal.String.Regex */
    c-[ss] { color: #6c71c4 } /* Literal.String.Symbol */
    c-[fm] { color: #268bd2 } /* Name.Function.Magic */
    c-[vc] { color: #cb4b16 } /* Name.Variable.Class */
    c-[vg] { color: #cb4b16 } /* Name.Variable.Global */
    c-[vi] { color: #cb4b16 } /* Name.Variable.Instance */
    c-[vm] { color: #cb4b16 } /* Name.Variable.Magic */
    c-[il] { color: #657b83 } /* Literal.Number.Integer.Long */
}
</style>
 </head><body class="h-entry toc-sidebar"><p id="toc-nav"><a id="toc-jump" href="#toc"><span aria-hidden="true">↑</span> <span>Jump to Table of Contents</span></a><a id="toc-toggle" href="#toc"><span aria-hidden="true">←</span> <span>Collapse Sidebar</span></a></p>
  <div class="head">
   <p data-fill-with="logo"></p>
   <h1 class="p-name no-ref" id="title">P3085R1<br><code class="highlight"><c- k="">noexcept</c-></code> policy for SD-9 (throws nothing)</h1>
   <h2 class="no-num no-toc no-ref heading settled" id="profile-and-date"><span class="content">Published Proposal, <time class="dt-updated" datetime="2024-03-17">2024-03-17</time></span></h2>
   <div data-fill-with="spec-metadata">
    <dl>
     <dt>This version:
     </dt><dd><a class="u-url" href="https://wg21.link/P3085">https://wg21.link/P3085</a>
     </dd><dt class="editor">Author:
     </dt><dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:ben.craig@gmail.com">Ben Craig</a>
     </dd><dt>Audience:
     </dt><dd>LEWG
     </dd><dt>Project:
     </dt><dd>ISO/IEC 14882 Programming Languages — C++, ISO/IEC JTC1/SC22/WG21
     </dd><dt>Source:
     </dt><dd><a href="https://github.com/ben-craig/freestanding_proposal/blob/master/library/throws_nothing_policy.bs">github.com/ben-craig/freestanding_proposal/blob/master/library/throws_nothing_policy.bs</a>
    </dd></dl>
   </div>
   <div data-fill-with="warning"></div>
   <hr title="Separator for header">
  </div>
  <div class="p-summary" data-fill-with="abstract">
   <h2 class="no-num no-toc no-ref heading settled" id="abstract"><span class="content">Abstract</span></h2>
  </div>
  <nav data-fill-with="table-of-contents" id="toc">
   <h2 class="no-num no-toc no-ref" id="contents">Table of Contents</h2>
   <ol class="toc" role="directory">
    <li>
     <a href="#rev"><span class="secno">1</span> <span class="content">Revision history</span></a>
     <ol class="toc">
      <li><a href="#rev-r1"><span class="secno">1.1</span> <span class="content">R1</span></a>
      </li><li><a href="#rev-r0"><span class="secno">1.2</span> <span class="content">R0</span></a>
     </li></ol>
    </li><li><a href="#intro"><span class="secno">2</span> <span class="content">Introduction</span></a>
    </li><li>
     <a href="#prior"><span class="secno">3</span> <span class="content">Prior <code class="highlight"><c- k="">noexcept</c-></code> Discussions</span></a>
     <ol class="toc">
      <li><a href="#history_papers"><span class="secno">3.1</span> <span class="content">History papers</span></a>
      </li><li><a href="#throws_nothing_papers"><span class="secno">3.2</span> <span class="content">Throws Nothing Rule</span></a>
      </li><li><a href="#narrow_noexcept_papers"><span class="secno">3.3</span> <span class="content">Narrow <code class="highlight"><c- k="">noexcept</c-></code> / Lakos Rule</span></a>
      </li><li><a href="#combined_papers"><span class="secno">3.4</span> <span class="content">Both</span></a>
     </li></ol>
    </li><li>
     <a href="#wording"><span class="secno">4</span> <span class="content">Policies in question</span></a>
     <ol class="toc">
      <li>
       <a href="#wording_common"><span class="secno">4.1</span> <span class="content">Common parts (proposed)</span></a>
       <ol class="toc">
        <li><a href="#wording_heading"><span class="secno">4.1.1</span> <span class="content"><code class="highlight"><c- k="">noexcept</c-></code> policy {#wording_heading}</span></a>
       </li></ol>
      </li><li><a href="#wording_throws_nothing"><span class="secno">4.2</span> <span class="content">Throws Nothing Rule (proposed)</span></a>
      </li><li><a href="#wording_lakos"><span class="secno">4.3</span> <span class="content">Narrow <code class="highlight"><c- k="">noexcept</c-></code> / Lakos Rule (not proposed in this revision)</span></a>
     </li></ol>
    </li><li><a href="#status_quo"><span class="secno">5</span> <span class="content">Status Quo</span></a>
    </li><li>
     <a href="#why_bother"><span class="secno">6</span> <span class="content">Why should we establish any <code class="highlight"><c- k="">noexcept</c-></code> policy?</span></a>
     <ol class="toc">
      <li><a href="#core_language_contracts"><span class="secno">6.1</span> <span class="content">Core-language Contracts</span></a>
      </li><li><a href="#consistency_over_preference"><span class="secno">6.2</span> <span class="content">Consistency over preference</span></a>
      </li><li><a href="#changes_in_direction"><span class="secno">6.3</span> <span class="content">Changes in direction</span></a>
      </li><li><a href="#cross_group_trust"><span class="secno">6.4</span> <span class="content">Cross group trust</span></a>
     </li></ol>
    </li><li><a href="#not_that_important"><span class="secno">7</span> <span class="content">Why the LEWG <code class="highlight"><c- k="">noexcept</c-></code> policy isn’t actually that important</span></a>
    </li><li>
     <a href="#arguments"><span class="secno">8</span> <span class="content">Arguments</span></a>
     <ol class="toc">
      <li><a href="#algorithmic_optimizations"><span class="secno">8.1</span> <span class="content">Algorithmic optimizations and exception safety</span></a>
      </li><li><a href="#backwards_compat"><span class="secno">8.2</span> <span class="content">Narrow to wide substitutability / backwards compatibility</span></a>
      </li><li>
       <a href="#codegen_changes"><span class="secno">8.3</span> <span class="content">Codegen changes</span></a>
       <ol class="toc">
        <li><a href="#modern_impls"><span class="secno">8.3.1</span> <span class="content">"Modern" implementations</span></a>
        </li><li><a href="#other_impls"><span class="secno">8.3.2</span> <span class="content">Other implementations</span></a>
        </li><li><a href="#size_bloat"><span class="secno">8.3.3</span> <span class="content">Bloat</span></a>
       </li></ol>
      </li><li>
       <a href="#library_testing"><span class="secno">8.4</span> <span class="content">Library Testing</span></a>
       <ol class="toc">
        <li>
         <a href="#arguments_core_language_contracts"><span class="secno">8.4.1</span> <span class="content">Core-language contracts</span></a>
         <ol class="toc">
          <li><a href="#check_on_the_outside"><span class="secno">8.4.1.1</span> <span class="content">Put the contract check on the outside of the <code class="highlight"><c- k="">noexcept</c-></code></span></a>
          </li><li><a href="#reflection_for_contracts"><span class="secno">8.4.1.2</span> <span class="content">Retrieve precondition and post-condition results via reflection</span></a>
          </li><li><a href="#contracts_change_noexcept"><span class="secno">8.4.1.3</span> <span class="content">Allow contract build modes to change the behavior of <code class="highlight"><c- k="">noexcept</c-></code></span></a>
         </li></ol>
        </li><li><a href="#extract_contracts_to_function"><span class="secno">8.4.2</span> <span class="content">Extract contract predicates to a function</span></a>
        </li><li><a href="#throwing_not_used_by_big_impls"><span class="secno">8.4.3</span> <span class="content">The widely deployed implementations don’t diagnose contract violations with exceptions</span></a>
        </li><li><a href="#noexcept_macro"><span class="secno">8.4.4</span> <span class="content"><code class="highlight"><c- k="">noexcept</c-></code> macro</span></a>
        </li><li><a href="#setjmp_longjmp"><span class="secno">8.4.5</span> <span class="content">setjmp/longjmp</span></a>
        </li><li><a href="#threads_fibers_signals"><span class="secno">8.4.6</span> <span class="content">Child threads, fibers, and signals</span></a>
        </li><li>
         <a href="#compiler_features"><span class="secno">8.4.7</span> <span class="content">Potentially mitigating compiler features</span></a>
         <ol class="toc">
          <li><a href="#make_noexcept_unchecked"><span class="secno">8.4.7.1</span> <span class="content">Compiler flag that makes <code class="highlight"><c- k="">noexcept</c-></code> unchecked</span></a>
          </li><li><a href="#magic_ub_exception"><span class="secno">8.4.7.2</span> <span class="content">Exploiting precondition undefined behavior to ignore termination</span></a>
         </li></ol>
        </li><li><a href="#death_tests"><span class="secno">8.4.8</span> <span class="content">Death tests</span></a>
       </li></ol>
      </li><li>
       <a href="#precondition_exception_in_production"><span class="secno">8.5</span> <span class="content">Using exceptions to diagnose precondition violations in production</span></a>
       <ol class="toc">
        <li><a href="#throwing_security"><span class="secno">8.5.1</span> <span class="content">Security dangers of throwing exceptions while in an unknown state</span></a>
        </li><li><a href="#temporary_continuation"><span class="secno">8.5.2</span> <span class="content">Temporary continuation</span></a>
        </li><li><a href="#more_ub_and_noexcept"><span class="secno">8.5.3</span> <span class="content">Likely to cause more UB or hit a destructor <code class="highlight"><c- k="">noexcept</c-></code></span></a>
        </li><li><a href="#garbage_in_garbage_out"><span class="secno">8.5.4</span> <span class="content">Postconditions only hold when preconditions hold</span></a>
        </li><li><a href="#noexcept_contradiction"><span class="secno">8.5.5</span> <span class="content">Precondition UB and <code class="highlight"><c- k="">noexcept</c-></code> contradict?</span></a>
       </li></ol>
      </li><li><a href="#termination_risk"><span class="secno">8.6</span> <span class="content">Termination risk</span></a>
      </li><li>
       <a href="#philosphy"><span class="secno">8.7</span> <span class="content">Philosophy</span></a>
       <ol class="toc">
        <li><a href="#noexcept_accuracy"><span class="secno">8.7.1</span> <span class="content"><code class="highlight"><c- k="">noexcept</c-></code>-accuracy</span></a>
        </li><li><a href="#can_already_add_noexcept"><span class="secno">8.7.2</span> <span class="content">Doesn’t matter since implementations can already add <code class="highlight"><c- k="">noexcept</c-></code></span></a>
        </li><li><a href="#stdlib_vs_user_lib_policies"><span class="secno">8.7.3</span> <span class="content">Standard library policies vs. C++ library policies</span></a>
        </li><li><a href="#impl_strategies_in_the_std"><span class="secno">8.7.4</span> <span class="content">Standard library implementation strategies need not be encoded in the C++ standard</span></a>
        </li><li><a href="#cleanup_preconditions"><span class="secno">8.7.5</span> <span class="content">Cleanup operations often have preconditions, and need to not throw</span></a>
        </li><li><a href="#invalid_and_indeterminate"><span class="secno">8.7.6</span> <span class="content">Narrow <code class="highlight"><c- k="">noexcept</c-></code> ignores implicit precondition of indeterminate values and invalid objects</span></a>
       </li></ol>
      </li><li><a href="#narrow_above_throws_nothing"><span class="secno">8.8</span> <span class="content">Can’t write narrow <code class="highlight"><c- k="">noexcept</c-></code> on top of throws nothing</span></a>
     </li></ol>
    </li><li>
     <a href="#notable_omissions"><span class="secno">9</span> <span class="content">Notable Omissions</span></a>
     <ol class="toc">
      <li><a href="#async_callbacks"><span class="secno">9.1</span> <span class="content">Asynchronous callbacks</span></a>
      </li><li><a href="#throwing_destructors"><span class="secno">9.2</span> <span class="content">Throwing destructors</span></a>
      </li><li><a href="#pervasive_conditional"><span class="secno">9.3</span> <span class="content">Pervasive conditional <code class="highlight"><c- k="">noexcept</c-></code></span></a>
      </li><li><a href="#c_compat"><span class="secno">9.4</span> <span class="content">C compatibility</span></a>
     </li></ol>
    </li><li>
     <a href="#principled_design"><span class="secno">10</span> <span class="content">Principled design</span></a>
     <ol class="toc">
      <li>
       <a href="#principle_descriptions"><span class="secno">10.1</span> <span class="content">Principle descriptions</span></a>
       <ol class="toc">
        <li><a href="#shared_principle_descriptions"><span class="secno">10.1.1</span> <span class="content">Shared principles</span></a>
        </li><li><a href="#new_principle_descriptions"><span class="secno">10.1.2</span> <span class="content">New principles</span></a>
        </li><li><a href="#omitted_principle_descriptions"><span class="secno">10.1.3</span> <span class="content">Omitted principles</span></a>
       </li></ol>
      </li><li><a href="#solution_descriptions"><span class="secno">10.2</span> <span class="content">Solution descriptions</span></a>
      </li><li><a href="#compliance_table"><span class="secno">10.3</span> <span class="content">Compliance table</span></a>
      </li><li><a href="#differences_with_lakos"><span class="secno">10.4</span> <span class="content">Comparison with <span title="P3005R0, Memorializing Principled-Design Policies for WG21">[Lakos3005]</span></span></a>
     </li></ol>
    </li><li>
     <a href="#suggested_polls"><span class="secno">11</span> <span class="content">Suggested polls</span></a>
     <ol class="toc">
      <li><a href="#better_than_nothing_poll"><span class="secno">11.1</span> <span class="content">Either policy is better than no policy</span></a>
      </li><li><a href="#head_to_head_poll"><span class="secno">11.2</span> <span class="content">Head-to-head policy poll</span></a>
      </li><li><a href="#narrow_lakos_poll"><span class="secno">11.3</span> <span class="content">Adopt the narrow <code class="highlight"><c- k="">noexcept</c-></code>/"Lakos rule" <code class="highlight"><c- k="">noexcept</c-></code> policy</span></a>
      </li><li><a href="#throws_nothing_poll"><span class="secno">11.4</span> <span class="content">Adopt the "Throws nothing rule" <code class="highlight"><c- k="">noexcept</c-></code> policy</span></a>
     </li></ol>
    </li><li><a href="#ack"><span class="secno">12</span> <span class="content">Acknowledgments</span></a>
    </li><li>
     <a href="#references"><span class="secno"></span> <span class="content">References</span></a>
     <ol class="toc">
      <li><a href="#informative"><span class="secno"></span> <span class="content">Informative References</span></a>
     </li></ol>
   </li></ol>
  </nav>
  <main>
   <h2 class="heading settled" data-level="1" id="rev"><span class="secno">1. </span><span class="content">Revision history</span><a class="self-link" href="#rev"></a></h2>
   <h3 class="heading settled" data-level="1.1" id="rev-r1"><span class="secno">1.1. </span><span class="content">R1</span><a class="self-link" href="#rev-r1"></a></h3>
   <ul>
    <li data-md="">
     <p>Added principled design and notable omissions sections.</p>
    </li><li data-md="">
     <p>Removed reference to undefined term "pass-through" function.</p>
   </li></ul>
   <h3 class="heading settled" data-level="1.2" id="rev-r0"><span class="secno">1.2. </span><span class="content">R0</span><a class="self-link" href="#rev-r0"></a></h3>
    First revision! 
   <h2 class="heading settled" data-level="2" id="intro"><span class="secno">2. </span><span class="content">Introduction</span><a class="self-link" href="#intro"></a></h2>
    The first priority of this paper is to establish a lasting policy on the usage of <code class="highlight"><c- k="">noexcept</c-></code> in the standard library that avoids re-litigation for a few years. 
   <p>The second priority is to establish the author’s preferred policy.</p>
   <p>This paper currently recommends the policy that functions that LEWG and LWG agree cannot throw should be marked unconditionally <code class="highlight"><c- k="">noexcept</c-></code>.</p>
   <p>This paper discusses an alternative policy that library functions 
that could exhibit undefined behavior due to precondition violations 
should not be marked <code class="highlight"><c- k="">noexcept</c-></code> (AKA the "Lakos rule", AKA the narrow <code class="highlight"><c- k="">noexcept</c-></code> policy).</p>
   <p>With luck, one of these two policies can gain consensus.</p>
   <h2 class="heading settled" data-level="3" id="prior"><span class="secno">3. </span><span class="content">Prior <code class="highlight"><c- k="">noexcept</c-></code> Discussions</span><a class="self-link" href="#prior"></a></h2>
   <h3 class="heading settled" data-level="3.1" id="history_papers"><span class="secno">3.1. </span><span class="content">History papers</span><a class="self-link" href="#history_papers"></a></h3>
   <ul>
    <li data-md="">
     <p><a href="https://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2855.html">N2855, Rvalue References and Exception Safety</a>, <a data-link-type="biblio" href="#biblio-gregorn2855" title="N2855, Rvalue References and Exception Safety">[GregorN2855]</a></p>
    </li><li data-md="">
     <p><a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2983.html">N2983, Allowing Move Constructors to Throw</a>, <a data-link-type="biblio" href="#biblio-abrahamsn2983" title="N2983, Allowing Move Constructors to Throw">[AbrahamsN2983]</a></p>
    </li><li data-md="">
     <p><a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3248.pdf">N3248, noexcept Prevents Library Validation.</a>, <a data-link-type="biblio" href="#biblio-meredithn3248" title="N3248, noexcept Prevents Library Validation">[MeredithN3248]</a></p>
    </li><li data-md="">
     <p><a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3279.pdf">N3279, Conservative use of noexcept in the Library</a>, <a data-link-type="biblio" href="#biblio-meredithn3279" title="N3279, Conservative use of noexcept in the Library">[MeredithN3279]</a></p>
    </li><li data-md="">
     <p><a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0884r0.pdf">P0884R0, Extending the noexcept Policy, Rev0</a>, <a data-link-type="biblio" href="#biblio-josuttis0884" title="P0884R0, Extending the noexcept Policy, Rev0">[Josuttis0884]</a></p>
    </li><li data-md="">
     <p><a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2920r0.pdf">P2920R0, Library Evolution Leadership’s Understanding of the Noexcept Policy History</a>, <a data-link-type="biblio" href="#biblio-lelbach2920" title="P2920R0, Library Evolution Leadership's Understanding of the Noexcept Policy History">[Lelbach2920]</a></p>
   </li></ul>
   <h3 class="heading settled" data-level="3.2" id="throws_nothing_papers"><span class="secno">3.2. </span><span class="content">Throws Nothing Rule</span><a class="self-link" href="#throws_nothing_papers"></a></h3>
   <ul>
    <li data-md="">
     <p><a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1656r2.html">P1656R2, "Throws: Nothing" should be noexcept</a>, <a data-link-type="biblio" href="#biblio-berg1656" title="P1656R2, &quot;Throws: Nothing&quot; should be noexcept">[Bergé1656]</a></p>
    </li><li data-md="">
     <p><a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2148r0.pdf">P2148R0, Library Evolution Design Guidelines</a>, <a data-link-type="biblio" href="#biblio-johnson2148" title="P2148R0, Library Evolution Design Guidelines">[Johnson2148]</a></p>
   </li></ul>
   <h3 class="heading settled" data-level="3.3" id="narrow_noexcept_papers"><span class="secno">3.3. </span><span class="content">Narrow <code class="highlight"><c- k="">noexcept</c-></code> / Lakos Rule</span><a class="self-link" href="#narrow_noexcept_papers"></a></h3>
   <ul>
    <li data-md="">
     <p><a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2831r0.pdf">P2831R0, Functions having a narrow contract should not be noexcept</a>, <a data-link-type="biblio" href="#biblio-doumler2831" title="P2831R0, Functions having a narrow contract should not be noexcept">[Doumler2831]</a></p>
    </li><li data-md="">
     <p><a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2837r0.pdf">P2837R0, Planning to Revisit the Lakos Rule</a>, <a data-link-type="biblio" href="#biblio-meredith2837" title="P2837R0, Planning to Revisit the Lakos Rule">[Meredith2837]</a></p>
    </li><li data-md="">
     <p><a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2861r0.pdf">P2861R0, The Lakos Rule: Narrow Contracts And noexcept Are Inherently Incompatible</a>, <a data-link-type="biblio" href="#biblio-lakos2861" title="P2861R0, The Lakos Rule: Narrow Contracts And noexcept Are Inherently Incompatible">[Lakos2861]</a></p>
    </li><li data-md="">
     <p><a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2949r0.pdf">P2949R0, Slides for P2861R0: Narrow Contracts and noexcept are Inherently Incompatable</a>, <a data-link-type="biblio" href="#biblio-lakos2949" title="P2949R0, Slides for P2861R0: Narrow Contracts and noexcept are Inherently Incompatable">[Lakos2949]</a></p>
    </li><li data-md="">
     <p><a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2946r0.pdf">P2946R0, A flexible solution to the problems of noexcept</a>, <a data-link-type="biblio" href="#biblio-halpern2946" title="P2946R0, A flexible solution to the problems of noexcept">[Halpern2946]</a></p>
   </li></ul>
   <h3 class="heading settled" data-level="3.4" id="combined_papers"><span class="secno">3.4. </span><span class="content">Both</span><a class="self-link" href="#combined_papers"></a></h3>
   <ul>
    <li data-md="">
     <p><a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2858r0.html">P2858R0, Noexcept vs contract violations</a>, <a data-link-type="biblio" href="#biblio-krzemieski2858" title="P2858R0, Noexcept vs contract violations">[Krzemieński2858]</a></p>
    </li><li data-md="">
     <p>This paper, P3085, <code class="highlight"><c- k="">noexcept</c-></code> policy for SD-9 (throws nothing)</p>
    </li><li data-md="">
     <p><a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3005r0.pdf">P3005R0, Memorializing Principled-Design Policies for WG21</a>, <a data-link-type="biblio" href="#biblio-lakos3005" title="P3005R0, Memorializing Principled-Design Policies for WG21">[Lakos3005]</a></p>
   </li></ul>
   <h2 class="heading settled" data-level="4" id="wording"><span class="secno">4. </span><span class="content">Policies in question</span><a class="self-link" href="#wording"></a></h2>
    These two policies only differ on point b. 
   <h3 class="heading settled" data-level="4.1" id="wording_common"><span class="secno">4.1. </span><span class="content">Common parts (proposed)</span><a class="self-link" href="#wording_common"></a></h3>
    This wording matches the shared wording from <a data-link-type="biblio" href="#biblio-berg1656" title="P1656R2, &quot;Throws: Nothing&quot; should be noexcept">[Bergé1656]</a> and <a data-link-type="biblio" href="#biblio-josuttis0884" title="P0884R0, Extending the noexcept Policy, Rev0">[Josuttis0884]</a>. 
   <p>Instructions to the editor: Please add the following to the "List of Standard Library Policies" in SD-9.</p>
   <blockquote>
    <h4 class="heading settled" data-level="4.1.1" id="wording_heading"><span class="secno">4.1.1. </span><span class="content"><code class="highlight"><c- k="">noexcept</c-></code> policy {#wording_heading}</span><a class="self-link" href="#wording_heading"></a></h4>
     Rationale reference: <a href="https://wg21.link/P3085">P3085</a> 
    <ol type="a">
     <li>No library destructor should throw. They shall use the implicitly supplied (non-throwing) exception specification.
     </li><li><i>EDITOR’S NOTE: Fill in this option with the selected policy.  See below.</i>
     </li><li>If a library swap function, move-constructor, or 
move-assignment operator is conditionally-wide (i.e. can be proven to 
not throw by applying the <code class="highlight"><c- k="">noexcept</c-></code> operator) then it should be marked as conditionally <code class="highlight"><c- k="">noexcept</c-></code>.
     </li><li>If a library type has wrapping semantics to transparently 
provide the same behavior as the underlying type, then default 
constructor, copy constructor, and copy-assignment operator should be 
marked as conditionally <code class="highlight"><c- k="">noexcept</c-></code> the underlying exception specification still holds.
     </li><li>No other function should use a conditional <code class="highlight"><c- k="">noexcept</c-></code> specification.
     </li><li>Library functions designed for compatibility with “C” code (such as the atomics facility), may be marked as unconditionally <code class="highlight"><c- k="">noexcept</c-></code>.
    </li></ol>
   </blockquote>
   <h3 class="heading settled" data-level="4.2" id="wording_throws_nothing"><span class="secno">4.2. </span><span class="content">Throws Nothing Rule (proposed)</span><a class="self-link" href="#wording_throws_nothing"></a></h3>
    This wording does not match <a data-link-type="biblio" href="#biblio-berg1656" title="P1656R2, &quot;Throws: Nothing&quot; should be noexcept">[Bergé1656]</a>, but it has the same intent. 
   <blockquote>
    <p>b. Each library function that will not throw when called with all preconditions satisfied should be marked as unconditionally <code class="highlight"><c- k="">noexcept</c-></code>.</p>
   </blockquote>
   <p>The wording in <a data-link-type="biblio" href="#biblio-berg1656" title="P1656R2, &quot;Throws: Nothing&quot; should be noexcept">[Bergé1656]</a> is as follows:</p>
   <blockquote>
    <p>b. Each library function that LEWG and LWG agree cannot throw, should be marked as unconditionally <code class="highlight"><c- k="">noexcept</c-></code>.</p>
   </blockquote>
   <p>The <a data-link-type="biblio" href="#biblio-berg1656" title="P1656R2, &quot;Throws: Nothing&quot; should be noexcept">[Bergé1656]</a>
 wording could be interpreted as disallowing narrow contract functions, 
since a function that is called without meeting preconditions could do 
anything, including throw.
That interpretation isn’t the intent of <a data-link-type="biblio" href="#biblio-berg1656" title="P1656R2, &quot;Throws: Nothing&quot; should be noexcept">[Bergé1656]</a>.</p>
   <h3 class="heading settled" data-level="4.3" id="wording_lakos"><span class="secno">4.3. </span><span class="content">Narrow <code class="highlight"><c- k="">noexcept</c-></code> / Lakos Rule (not proposed in this revision)</span><a class="self-link" href="#wording_lakos"></a></h3>
    This wording matches the wording in <a data-link-type="biblio" href="#biblio-josuttis0884" title="P0884R0, Extending the noexcept Policy, Rev0">[Josuttis0884]</a>. 
   <blockquote>
    <p>b. Each library function having a <em>wide</em> contract (i.e., 
does not specify undefined behavior due to a precondition) that the LWG 
agree cannot throw, should be marked as unconditionally <code class="highlight"><c- k="">noexcept</c-></code>.</p>
   </blockquote>
   <h2 class="heading settled" data-level="5" id="status_quo"><span class="secno">5. </span><span class="content">Status Quo</span><a class="self-link" href="#status_quo"></a></h2>
    Currently, there is no policy on <code class="highlight"><c- k="">noexcept</c-></code>.
Between 2011 and 2020, <code class="highlight"><c- k="">noexcept</c-></code> was applied to the standard library in line with the narrow <code class="highlight"><c- k="">noexcept</c-></code> rule <a data-link-type="biblio" href="#biblio-meredithn3279" title="N3279, Conservative use of noexcept in the Library">[MeredithN3279]</a> <a data-link-type="biblio" href="#biblio-josuttis0884" title="P0884R0, Extending the noexcept Policy, Rev0">[Josuttis0884]</a>.
In 2020, the throws nothing rule was proposed <a data-link-type="biblio" href="#biblio-berg1656" title="P1656R2, &quot;Throws: Nothing&quot; should be noexcept">[Bergé1656]</a>.
The designs that LEWG has forwarded to LWG between 2020 and the present day have been following the narrow <code class="highlight"><c- k="">noexcept</c-></code> rule. 
   <p>There are 78 occurrences of "Throws: Nothing." in the standard <a data-link-type="biblio" href="#biblio-cpp2023-12" title="N4971: Working Draft, Programming Languages -- C++">[Cpp2023-12]</a>, but this number is misleading as many of the usages are in blanket wording that gets applied to multiple classes.
The Microsoft Visual Studio 2022 Preview implementation (version 14.38.32919) annotates each <code class="highlight"><c- k="">noexcept</c-></code> they strengthen with a <code class="highlight"><c- d="">/* strengthened */</c-></code> comment.
There are 633 hits of the "noexcept /* strengthened */" string in the headers for this implementation.
All of these are either definitions of functions, or macros that make stamping out <code class="highlight"><c- o="">&lt;</c-><c- n="">cmath</c-><c- o="">&gt;</c-></code> overload definitions easier.
In other words, these hits aren’t counting both forward declarations plus definitions, they are only counting definitions.
This search omits any conditionally <code class="highlight"><c- k="">noexcept</c-></code> functions.</p>
   <p>There are roughly 3,600 instances of the string "noexcept;" in the standard.
A few of these are in examples.
For most <code class="highlight"><c- k="">noexcept</c-></code> functions, "noexcept;" will show up twice in the standard <a data-link-type="biblio" href="#biblio-cpp2023-12" title="N4971: Working Draft, Programming Languages -- C++">[Cpp2023-12]</a>, once in a synopsis and once in the detailed specification.
This means there are approximately 1,800 unconditionally <code class="highlight"><c- k="">noexcept</c-></code> functions in the standard.
This search omits any conditionally <code class="highlight"><c- k="">noexcept</c-></code> functions.</p>
   <h2 class="heading settled" data-level="6" id="why_bother"><span class="secno">6. </span><span class="content">Why should we establish any <code class="highlight"><c- k="">noexcept</c-></code> policy?</span><a class="self-link" href="#why_bother"></a></h2>
   <h3 class="heading settled" data-level="6.1" id="core_language_contracts"><span class="secno">6.1. </span><span class="content">Core-language Contracts</span><a class="self-link" href="#core_language_contracts"></a></h3>
    Interactions between <code class="highlight"><c- k="">noexcept</c-></code>
 and the upcoming core-language contracts facilities is likely to be 
significant.
It would be unfortunate if decisions in the library prevented the 
core-language contracts work from reaching its full potential. 
   <p><a data-link-type="biblio" href="#biblio-meredith2837" title="P2837R0, Planning to Revisit the Lakos Rule">[Meredith2837]</a>
 argues that the interaction may be significant and unpredictable enough
 that it would be better to proceed with no policy in the short term, 
rather than settle on a policy that will immediately get in the way of 
contracts.</p>
   <p>If we don’t set a policy, then we leave it to paper authors and LEWG to determine the proper <code class="highlight"><c- k="">noexcept</c-></code> specifier on a per-function basis.
This is likely to cause a great deal of inconsistency in the interim.</p>
   <h3 class="heading settled" data-level="6.2" id="consistency_over_preference"><span class="secno">6.2. </span><span class="content">Consistency over preference</span><a class="self-link" href="#consistency_over_preference"></a></h3>
   <p>There are some design areas where the difference in two choices is
 of little consequence.
LEWG will often spend some time rediscovering the trade-offs and 
existing practice around the differences, and then make a somewhat 
arbitrary decision.
In these cases, LEWG tends to bias towards "whatever the bulk of the 
standard is currently doing".</p>
   <p>LEWG could become more self consistent by documenting one way, and
 then requiring authors to either follow the policy, or provide 
rationale for why the policy should not be applied in this case.</p>
   <p>The explicit-ness of multi-argument constructors is one such area <a data-link-type="biblio" href="#biblio-voutilainen2711" title="P2711R1, Making multi-param constructors of views explicit">[Voutilainen2711]</a>.</p>
   <h3 class="heading settled" data-level="6.3" id="changes_in_direction"><span class="secno">6.3. </span><span class="content">Changes in direction</span><a class="self-link" href="#changes_in_direction"></a></h3>
   <p>Sometimes, LEWG follows one design pattern in the standard, then discovers or invents a new pattern.
The new pattern is inconsistent with the old pattern.
Authors then wonder whether to follow the new pattern or old pattern.</p>
   <p>This is a reasonable place for LEWG to document a policy.</p>
   <p>Using hidden <code class="highlight"><c- k="">friend</c-></code>s for non-member operators is one example of a change in direction.
Whether to make all new "free functions" in the standard library customization point objects (like <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">ranges</c-></code>) is another.</p>
   <h3 class="heading settled" data-level="6.4" id="cross_group_trust"><span class="secno">6.4. </span><span class="content">Cross group trust</span><a class="self-link" href="#cross_group_trust"></a></h3>
   <p>There are a lot of discussions happening concurrently within WG21.
Sometimes, one group wants to rely on conventions from another group.
These policies help people focus on the groups they are needed, rather 
than spend a large portion of their time ensuring their policy is 
followed (or not) in LEWG.</p>
   <p>An example policy here would be ensuring that <code class="highlight"><c- k="">const</c-></code> means either shallow bitwise const or internally synchronized.
The concurrency study group is likely relying on that convention to be followed, so changing <code class="highlight"><c- k="">const</c-></code> directions would cause surprise.</p>
   <h2 class="heading settled" data-level="7" id="not_that_important"><span class="secno">7. </span><span class="content">Why the LEWG <code class="highlight"><c- k="">noexcept</c-></code> policy isn’t actually that important</span><a class="self-link" href="#not_that_important"></a></h2>
   <p>Implementations already strengthen the <code class="highlight"><c- k="">noexcept</c-></code> status of many STL functions.
MSVC STL, libc++, and libstdc++ all mark <code class="highlight"><c- n="">vector</c-><c- o="">::</c-><c- n="">back</c-><c- p="">()</c-></code>, <code class="highlight"><c- n="">vector</c-><c- o="">::</c-><c- k="">operator</c-><c- p="">[]</c-></code>, and many other functions as <code class="highlight"><c- k="">noexcept</c-></code>.</p>
   <p>Marking existing functions in the standard <code class="highlight"><c- k="">noexcept</c-></code> will change the results of very few instances of the <code class="highlight"><c- k="">noexcept</c-></code> operator in practice.</p>
   <p>If the committee continues to permit implementations to strengthen the <code class="highlight"><c- k="">noexcept</c-></code> status of functions, then implementations won’t change.</p>
   <p>If the committee chooses to remove this permission, 
implementations will either ignore the requirement and be 
non-conforming, or they will accept the code breakage that the backwards
 compatibility arguments <a href="#backwards_compat">§ 8.2 Narrow to wide substitutability / backwards compatibility</a> are trying to avoid.
If we are breaking compatibility in this way once, we may very well break it again in the future.
The main way changing the <code class="highlight"><c- k="">noexcept</c-></code> policy changes things for standardization and users is if we remove the permission to strengthen <code class="highlight"><c- k="">noexcept</c-></code> and implementations grudgingly take a one time (but not an N time) compatibility hit.</p>
   <p>Note that this paper makes no attempt to change the <code class="highlight"><c- k="">noexcept</c-></code> strengthening rules in either it’s proposed rules or the presented alternative.</p>
   <h2 class="heading settled" data-level="8" id="arguments"><span class="secno">8. </span><span class="content">Arguments</span><a class="self-link" href="#arguments"></a></h2>
    This section is organized by topic, and not by policy.
That means that sections discuss one topic at a time (e.g. testing), and then discuss the affect of the policies on the topic. 
   <h3 class="heading settled" data-level="8.1" id="algorithmic_optimizations"><span class="secno">8.1. </span><span class="content">Algorithmic optimizations and exception safety</span><a class="self-link" href="#algorithmic_optimizations"></a></h3>
    <a data-link-type="biblio" href="#biblio-gregorn2855" title="N2855, Rvalue References and Exception Safety">[GregorN2855]</a>, <a data-link-type="biblio" href="#biblio-abrahamsn2983" title="N2983, Allowing Move Constructors to Throw">[AbrahamsN2983]</a>, <a data-link-type="biblio" href="#biblio-meredithn3248" title="N3248, noexcept Prevents Library Validation">[MeredithN3248]</a> 
   <p>The original, primary motivation for <code class="highlight"><c- k="">noexcept</c-></code> was to make it possible for <code class="highlight"><c- n="">vector</c-></code> and similar constructs to take advantage of <code class="highlight"><c- n="">move</c-></code> optimizations, without breaking existing code (e.g. <code class="highlight"><c- n="">vector</c-></code>’s strong exception guarantee).</p>
   <p>This motivation and use case is uncontested in the various papers debating the usage of <code class="highlight"><c- k="">noexcept</c-></code>, so this paper will not spend further time on it.</p>
   <p>On most implementations, disabling exceptions does not change the result of the <code class="highlight"><c- k="">noexcept</c-></code> operator (The discontinued Intel ICC makes the <code class="highlight"><c- k="">noexcept</c-></code> operator return <code class="highlight">true</code> unconditionally under <code class="highlight"><c- o="">-</c-><c- n="">fno</c-><c- o="">-</c-><c- n="">exceptions</c-></code>).
This means that <code class="highlight"><c- k="">noexcept</c-></code> is still needed in order to opt-in to algorithmic optimizations, even when exceptions are disabled.</p>
   <h3 class="heading settled" data-level="8.2" id="backwards_compat"><span class="secno">8.2. </span><span class="content">Narrow to wide substitutability / backwards compatibility</span><a class="self-link" href="#backwards_compat"></a></h3>
    <a data-link-type="biblio" href="#biblio-doumler2831" title="P2831R0, Functions having a narrow contract should not be noexcept">[Doumler2831]</a>, <a data-link-type="biblio" href="#biblio-lakos2949" title="P2949R0, Slides for P2861R0: Narrow Contracts and noexcept are Inherently Incompatable">[Lakos2949]</a>, <a data-link-type="biblio" href="#biblio-lakos2861" title="P2861R0, The Lakos Rule: Narrow Contracts And noexcept Are Inherently Incompatible">[Lakos2861]</a> 
   <p>Suppose we have a function <code class="highlight"><c- b="">void</c-> <c- n="">unchecked_f</c-><c- p="">(</c-><c- b="">int</c-> <c- n="">x</c-><c- p="">)</c-></code> with a precondition of <code class="highlight"><c- n="">x</c-> <c- o="">&gt;</c-> <c- mi="">0</c-></code>. <code class="highlight"><c- n="">unchecked_f</c-></code> has undefined behavior when the precondition is violated.</p>
   <p>Now suppose we have a function <code class="highlight"><c- b="">void</c-> <c- n="">checked_f</c-><c- p="">(</c-><c- b="">int</c-> <c- n="">x</c-><c- p="">)</c-></code> that has the same behavior as <code class="highlight"><c- n="">unchecked_f</c-></code> when the precondition is met, but it throws an exception when the precondition is violated. <code class="highlight"><c- n="">checked_f</c-></code> and <code class="highlight"><c- n="">unchecked_f</c-></code> are substitutable for each other, as all in-contract uses behave the same.</p>
   <p>Now suppose we have a function <code class="highlight"><c- b="">void</c-> <c- n="">noexcept_f</c-><c- p="">(</c-><c- b="">int</c-> <c- n="">x</c-><c- p="">)</c-> <c- k="">noexcept</c-></code> that has the same behavior as <code class="highlight"><c- n="">unchecked_f</c-></code> when the precondition is met. <code class="highlight"><c- n="">noexcept_f</c-></code> and <code class="highlight"><c- n="">unchecked_f</c-></code> aren’t substitutable with each other, due to the change in behavior of the <code class="highlight"><c- k="">noexcept</c-></code> operator. <code class="highlight"><c- k="">noexcept</c-><c- p="">(</c-><c- n="">noexcept_f</c-><c- p="">(</c-><c- mi="">0</c-><c- p="">))</c-></code> returns <code class="highlight">true</code>, and <code class="highlight"><c- k="">noexcept</c-><c- p="">(</c-><c- n="">unchecked_f</c-><c- p="">(</c-><c- mi="">0</c-><c- p="">))</c-></code> returns <code class="highlight">false</code>.
This change in behavior constrains implementations and the C++ committee.</p>
   <p>In theory, avoiding <code class="highlight"><c- k="">noexcept</c-></code> gives WG21 more latitude to make changes in the future.
In practice, this latitude is unneeded, and difficult to use.</p>
   <p>The author is unaware of any previous proposal that attempted to 
make a "Throws: nothing" function released in one standard into a 
function that could throw something in a later standard.
This suggests that this freedom to change isn’t that valuable in 
practice.
We’ve had the freedom, but haven’t needed it or used it.</p>
   <p>Using the freedom to make an out-of-contract call throw an exception would be a compatibility break in practice.
MSVC STL, libc++, and libstdc++ all mark <code class="highlight"><c- n="">vector</c-><c- o="">::</c-><c- n="">back</c-><c- p="">()</c-></code>, <code class="highlight"><c- n="">vector</c-><c- o="">::</c-><c- k="">operator</c-><c- p="">[]</c-></code>, and many other functions as <code class="highlight"><c- k="">noexcept</c-></code>.
If we were to require <code class="highlight"><c- n="">vector</c-><c- o="">::</c-><c- n="">back</c-><c- p="">()</c-></code> to be <code class="highlight"><c- k="">noexcept</c-><c- p="">(</c->false<c- p="">)</c-></code>
 so that it could throw when the container is empty, it would cause a 
(minor) break for the majority of C++ code bases migrating to that 
standard due to the change in the <code class="highlight"><c- k="">noexcept</c-></code> operator’s result.
Perhaps such a break would be small enough to gain consensus in WG21 though.</p>
   <p>Major implementations don’t currently use <code class="highlight"><c- k="">noexcept</c-></code> latitude to implement throwing precondition checks.
The three major implementations (MSVC STL, libstdc++, and libc++) all have checked implementations.
All three use some variation of termination as their mechanism of handling a failed check.</p>
   <p>Less prevalent implementations do use such latitude for checked implementations and library testing.</p>
   <h3 class="heading settled" data-level="8.3" id="codegen_changes"><span class="secno">8.3. </span><span class="content">Codegen changes</span><a class="self-link" href="#codegen_changes"></a></h3>
   <h4 class="heading settled" data-level="8.3.1" id="modern_impls"><span class="secno">8.3.1. </span><span class="content">"Modern" implementations</span><a class="self-link" href="#modern_impls"></a></h4>
    Most platforms use the "table-based" implementation strategy for exceptions.
The combinations of (x86-64, ARM, Aarch64) X (Windows, Linux, iOS, OSX) all use table-based exceptions. 
   <p>With table-based implementations, <code class="highlight"><c- k="">noexcept</c-></code> changes the generated assembly.
There are sometimes extra stack manipulations, and minor bookkeeping changes, but no extra branches.
Those minor changes affect the performance in a small and measurable way, but sometimes that difference is positive (for <code class="highlight"><c- k="">noexcept</c-></code>), and sometimes negative (against <code class="highlight"><c- k="">noexcept</c-></code>).
The magnitude of the difference is under six cycles for the programs and compilers tested <a data-link-type="biblio" href="#biblio-craig1886" title="P1886R0, Error speed benchmarking">[Craig1886]</a>.
Full application testing might show some instruction cache effects, but 
it is even more likely that any differences would be lost in the noise 
and immeasurable.</p>
   <h4 class="heading settled" data-level="8.3.2" id="other_impls"><span class="secno">8.3.2. </span><span class="content">Other implementations</span><a class="self-link" href="#other_impls"></a></h4>
    <a data-link-type="biblio" href="#biblio-doumler2831" title="P2831R0, Functions having a narrow contract should not be noexcept">[Doumler2831]</a> 
   <p>Not all implementations use the table-based implementation strategy.
These implementations have more substantial bookkeeping relative to table-based implementations.</p>
   <p>The most well known of these implementations is the Microsoft 
Windows 32-bit x86 implementation.
Each new cleanup context requires manipulating a linked list of cleanup 
actions, even on the happy path.
This results in substantial extra code, and more than a 20% execution 
performance penalty with micro-benchmarks relative to exceptions being 
disabled <a data-link-type="biblio" href="#biblio-craig1886" title="P1886R0, Error speed benchmarking">[Craig1886]</a>.
With heavy use of <code class="highlight"><c- k="">noexcept</c-></code>, the overhead can be removed.
The default and recommended exception project settings of the Microsoft Visual Studio compilers is <code class="highlight"><c- o="">/</c-><c- n="">EHsc</c-></code>, which (non-conformingly) makes <code class="highlight"><c- k="">extern</c-> <c- s="">"C"</c-></code> functions <code class="highlight"><c- k="">noexcept</c-></code> by default as a way to reduce exception overhead.</p>
   <p>While the days of peak Microsoft Windows for 32-bit x86 are far 
behind us, new compilers targeting the platform are still regularly 
released and downloaded.
Microsoft Visual Studio 2022 (the latest version at time of writing) 
still ships compilers targeting 32-bit Windows.
Clang 17.0.5 (released on Nov 14, 2023) still targets 32-bit Windows.
Download statistics for Clang binaries are available through the GitHub 
API.</p>
<pre class="highlight"><c- c1="">// Clang 17.0.5 download statistices, gathered on Feb 2, 2024</c->
<c- c1="">// https://api.github.com/repos/llvm/llvm-project/releases</c->
<c- n="">LLVM</c-><c- mf="">-17.0.5</c-><c- o="">-</c-><c- n="">win32</c-><c- p="">.</c-><c- n="">exe</c-> <c- o="">:</c-> <c- mi="">1422</c-> <c- n="">downloads</c->
<c- n="">LLVM</c-><c- mf="">-17.0.5</c-><c- o="">-</c-><c- n="">win64</c-><c- p="">.</c-><c- n="">exe</c-> <c- o="">:</c-> <c- mi="">22370</c-> <c- n="">downloads</c->
<c- n="">LLVM</c-><c- mf="">-17.0.5</c-><c- o="">-</c-><c- n="">woa64</c-><c- p="">.</c-><c- n="">exe</c-> <c- o="">:</c-> <c- mi="">304</c-> <c- n="">downloads</c->
<c- n="">clang</c-><c- o="">+</c-><c- n="">llvm</c-><c- mf="">-17.0.5</c-><c- o="">-</c-><c- n="">aarch64</c-><c- o="">-</c-><c- n="">linux</c-><c- o="">-</c-><c- n="">gnu</c-><c- p="">.</c-><c- n="">tar</c-><c- p="">.</c-><c- n="">xz</c-> <c- o="">:</c-> <c- mi="">532</c-> <c- n="">downloads</c->
<c- n="">clang</c-><c- o="">+</c-><c- n="">llvm</c-><c- mf="">-17.0.5</c-><c- o="">-</c-><c- n="">arm64</c-><c- o="">-</c-><c- n="">apple</c-><c- o="">-</c-><c- n="">darwin22</c-><c- mf="">.0</c-><c- p="">.</c-><c- n="">tar</c-><c- p="">.</c-><c- n="">xz</c-> <c- o="">:</c-> <c- mi="">585</c-> <c- n="">downloads</c->
<c- n="">clang</c-><c- o="">+</c-><c- n="">llvm</c-><c- mf="">-17.0.5</c-><c- o="">-</c-><c- n="">x86_64</c->…<c- n="">gnu</c-><c- o="">-</c-><c- n="">ubuntu</c-><c- mf="">-22.04</c-><c- p="">.</c-><c- n="">tar</c-><c- p="">.</c-><c- n="">xz</c-> <c- o="">:</c-> <c- mi="">1803</c-> <c- n="">downloads</c->
<c- n="">clang</c-><c- o="">+</c-><c- n="">llvm</c-><c- mf="">-17.0.5</c-><c- o="">-</c-><c- n="">powerpc64</c-><c- o="">-</c-><c- n="">ibm</c-><c- o="">-</c-><c- n="">aix</c-><c- mf="">-7.2</c-><c- p="">.</c-><c- n="">tar</c-><c- p="">.</c-><c- n="">xz</c-> <c- o="">:</c-> <c- mi="">69</c-> <c- n="">downloads</c->
</pre>
   <p>Readers should not try to make too many inferences about the 
relative popularity of platforms based on these numbers, as developers 
can get compiler releases from multiple sources that wouldn’t register 
on the GitHub download page.
Regardless, the Microsoft Windows 32-bit platform still gets used, even 
with the most recent compilers, so it should not be brushed off as 
irrelevant.</p>
   <p>James Renwick has an alternative implementation of exceptions <a data-link-type="biblio" href="#biblio-renwick2019" title="Low-cost deterministic C++ exceptions for embedded systems">[Renwick2019]</a> with the intent of improving determinism in embedded systems.
This implementation also needs to manipulate bookkeeping information in each new cleanup context.
The bookkeeping information is passed along to potentially throwing functions through a hidden parameter. <code class="highlight"><c- k="">noexcept</c-></code> can remove the cost of the hidden parameter, but can introduce a new cleanup context.</p>
   <p>On GPUs, there is a large cost to having additional control flow edges.
Using <code class="highlight"><c- k="">noexcept</c-></code> can remove control flow edges.
However, to the author’s knowledge, no GPU currently supports C++ exceptions.</p>
   <h4 class="heading settled" data-level="8.3.3" id="size_bloat"><span class="secno">8.3.3. </span><span class="content">Bloat</span><a class="self-link" href="#size_bloat"></a></h4>
    <a data-link-type="biblio" href="#biblio-berg1656" title="P1656R2, &quot;Throws: Nothing&quot; should be noexcept">[Bergé1656]</a>, <a data-link-type="biblio" href="#biblio-doumler2831" title="P2831R0, Functions having a narrow contract should not be noexcept">[Doumler2831]</a>, <a data-link-type="biblio" href="#biblio-lakos2861" title="P2861R0, The Lakos Rule: Narrow Contracts And noexcept Are Inherently Incompatible">[Lakos2861]</a> 
   <p>The "tables" backing table-based exception handling, and the code implementing non-table-based bookkeeping all consume space.
Adding <code class="highlight"><c- k="">noexcept</c-></code> can reduce code bloat, as this can reduce the amount of information that needs to go into tables or bookkeeping.
Adding <code class="highlight"><c- k="">noexcept</c-></code> can also cause bloat if the <code class="highlight"><c- k="">noexcept</c-></code>
 function calls potentially throwing functions, as this transformation 
may need to introduce table entries or bookkeeping to ensure that <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">terminate</c-></code> gets called.</p>
   <p>In Compiler Explorer, bloat is best examined by disabling debug information (<code class="highlight"><c- o="">-</c-><c- n="">g0</c-></code> for Clang and GCC), enabling optimizations (<code class="highlight"><c- o="">-</c-><c- n="">O2</c-></code>),
 and leaving directives in the output (uncheck the box in "Filter...").
As a (very rough) estimate of bloat, we can use lines of assembly output
 as a proxy.
Some of the lines don’t end up as bytes in the resulting binary, but 
many do show up, often as variable length integers.
Measuring the results on actual binaries is substantially more 
difficult, due to section alignment quantizing and obfuscating size 
differences. <a data-link-type="biblio" href="#biblio-craig1640" title="P1640R1, Error size benchmarking: Redux">[Craig1640]</a>
 presents size benchmarks comparing exceptions to abort, and some of 
these measurements can be used as proxy byte-based statistics for <code class="highlight"><c- k="">noexcept</c-></code> bloat.</p>
   <p><a href="https://godbolt.org/z/MoGMh9Gxo">This code</a> makes it possible to see what happens to the quantity of assembly when switching whether <code class="highlight"><c- n="">caller</c-></code> is <code class="highlight"><c- k="">noexcept</c-></code> or not, and whether <code class="highlight"><c- n="">callee</c-></code> is <code class="highlight"><c- k="">noexcept</c-></code> or not.  All measurements are in the very rough lines of assembly measurement.</p>
   <table>
    <tbody>
     <tr>
      <th>Compiler
      </th><th><code class="highlight"><c- k="">noexcept</c-><c- p="">(</c->false<c- p="">)</c-></code> calls <code class="highlight"><c- k="">noexcept</c-><c- p="">(</c->false<c- p="">)</c-></code>
      </th><th><code class="highlight"><c- k="">noexcept</c-><c- p="">(</c->false<c- p="">)</c-></code> calls <code class="highlight"><c- k="">noexcept</c-><c- p="">(</c->true<c- p="">)</c-></code>
      </th><th><code class="highlight"><c- k="">noexcept</c-><c- p="">(</c->true<c- p="">)</c-></code> calls <code class="highlight"><c- k="">noexcept</c-><c- p="">(</c->false<c- p="">)</c-></code>
      </th><th><code class="highlight"><c- k="">noexcept</c-><c- p="">(</c->true<c- p="">)</c-></code> calls <code class="highlight"><c- k="">noexcept</c-><c- p="">(</c->true<c- p="">)</c-></code>
     </th></tr><tr>
      <td>x86 msvc v19.38
      </td><td>76
      </td><td>25
      </td><td>70
      </td><td>25
     </td></tr><tr>
      <td>x64 msvc v19.38
      </td><td>44
      </td><td>26
      </td><td>37
      </td><td>26
     </td></tr><tr>
      <td>x86-64 gcc 13.2
      </td><td>85
      </td><td>20
      </td><td>32
      </td><td>20
     </td></tr><tr>
      <td>x86-64 clang 17.0.1
      </td><td>68
      </td><td>22
      </td><td>76
      </td><td>22
     </td></tr><tr>
      <td>ARM64 gcc 13.2.0
      </td><td>69
      </td><td>26
      </td><td>46
      </td><td>26
     </td></tr><tr>
      <td>armv8-a clang 17.0.1
      </td><td>74
      </td><td>30
      </td><td>88
      </td><td>30
   </td></tr></tbody></table>
   <p>For many platforms and applications, this bloat is inconsequential.
For many platforms and applications that are size constrained, exceptions are already disabled.
When exceptions are disabled, the "<code class="highlight"><c- k="">noexcept</c-><c- p="">(</c->true<c- p="">)</c-></code> calls <code class="highlight"><c- k="">noexcept</c-><c- p="">(</c->true<c- p="">)</c-></code>" code and the exception disabled code take the same number of lines of assembly.</p>
   <h3 class="heading settled" data-level="8.4" id="library_testing"><span class="secno">8.4. </span><span class="content">Library Testing</span><a class="self-link" href="#library_testing"></a></h3>
    <a data-link-type="biblio" href="#biblio-meredithn3248" title="N3248, noexcept Prevents Library Validation">[MeredithN3248]</a>, <a data-link-type="biblio" href="#biblio-doumler2831" title="P2831R0, Functions having a narrow contract should not be noexcept">[Doumler2831]</a> 
   <p>Implementations often constrain some undefined behavior for 
out-of-contract function invocations, particularly in debug and checked 
modes.
"Negative testing" validates that the assertion / contract checks are 
authored correctly, and that the resulting constrained undefined 
behavior does the expected thing.
The contract checks are code, and code needs testing.</p>
   <p>Negative tests can be authored for codebases using the narrow <code class="highlight"><c- k="">noexcept</c-></code> rule or the throws nothing <code class="highlight"><c- k="">noexcept</c-></code> rule, but it is substantially easier to do so for narrow <code class="highlight"><c- k="">noexcept</c-></code> rule codebases.</p>
   <h4 class="heading settled" data-level="8.4.1" id="arguments_core_language_contracts"><span class="secno">8.4.1. </span><span class="content">Core-language contracts</span><a class="self-link" href="#arguments_core_language_contracts"></a></h4>
   <p>Usage of the proposed core-language contracts facilities will need to be tested. <code class="highlight"><c- k="">noexcept</c-></code> will present testing challenges when violations of core-language contracts are configured to throw an exception.
Death tests are an option, but they have a large set of challenges on their own.</p>
   <h5 class="heading settled" data-level="8.4.1.1" id="check_on_the_outside"><span class="secno">8.4.1.1. </span><span class="content">Put the contract check on the outside of the <code class="highlight"><c- k="">noexcept</c-></code></span><a class="self-link" href="#check_on_the_outside"></a></h5>
   <p>One of the design decisions that core-language contracts needs to make is to decide exactly where the checks will be run.
If precondition and post-condition checks happen within the callee (i.e. inside the <code class="highlight"><c- k="">noexcept</c-></code>), then failed preconditions and post-conditions checks set to throw will cause the program to terminate.
If those checks happen in the caller of the function (i.e. outside the <code class="highlight"><c- k="">noexcept</c-></code>), then at least one layer of throwing can still work in testing.
Deeply nested checks can still cause a terminate if they end up propagating through a different <code class="highlight"><c- k="">noexcept</c-></code>.
If precondition and post-condition checks in the caller of a <code class="highlight"><c- k="">noexcept</c-></code> function, then that would resolve most of the core-language contracts negative testing issues.</p>
   <p>Putting preconditions and post-conditions outside the <code class="highlight"><c- k="">noexcept</c-></code> doesn’t help with core-language contract asserts.</p>
   <p><a data-link-type="biblio" href="#biblio-voutilainen2780" title="P2780R0, Caller-side precondition checking, and Eval_and_throw">[Voutilainen2780]</a> discusses this point, as well as discussing other benefits involving calling external libraries.
It also discusses the challenges of this approach with regards to indirect calls and multiply evaluated preconditions.</p>
   <p>Caller-side precondition checking is likely to be less efficient 
in terms of code size compared to callee-side precondition checking.</p>
   <h5 class="heading settled" data-level="8.4.1.2" id="reflection_for_contracts"><span class="secno">8.4.1.2. </span><span class="content">Retrieve precondition and post-condition results via reflection</span><a class="self-link" href="#reflection_for_contracts"></a></h5>
    Suppose we have the following function + contract: 
<pre class="language-c++ highlight"><c- b="">int</c-> <c- nf="">f</c-><c- p="">(</c-><c- b="">int</c-> <c- n="">x</c-><c- p="">)</c-> <c- n="">noexcept</c-> 
  <c- n="">pre</c-> <c- p="">(</c-><c- n="">x</c-> <c- o="">&gt;=</c-> <c- mi="">0</c-><c- p="">)</c->
  <c- n="">post</c-><c- p="">(</c-><c- n="">r</c-> <c- o="">:</c-> <c- n="">r</c-> <c- o="">%</c-> <c- mi="">2</c-> <c- o="">==</c-> <c- mi="">0</c-><c- p="">);</c->
</pre>
   <p>Now imagine we had reflection facilities that let us do something like the following:</p>
<pre class="language-c++ highlight"><c- c1="">// // evaluate contracts of f(x) without calling f(x)</c->
<c- n="">EXPECT_TRUE</c-><c- p="">(</c->  <c- n="">$evaluate_pre</c-><c- p="">(</c-><c- n="">f</c-><c- p="">,</c-> <c- mi="">20</c-><c- p="">)</c-> <c- p="">);</c->
<c- n="">EXPECT_FALSE</c-><c- p="">(</c-> <c- n="">$evaluate_pre</c-><c- p="">(</c-><c- n="">f</c-><c- p="">,</c-> <c- mi="">-1</c-><c- p="">)</c-> <c- p="">);</c->
<c- n="">EXPECT_TRUE</c-><c- p="">(</c->  <c- n="">$evaluate_post</c-><c- p="">(</c-><c- n="">f</c-><c- p="">,</c-> <c- mi="">2</c-><c- p="">,</c-> <c- mi="">20</c-><c- p="">)</c-> <c- p="">);</c-> <c- c1="">// x = 20, returns 2</c->
<c- n="">EXPECT_FALSE</c-><c- p="">(</c-> <c- n="">$evaluate_post</c-><c- p="">(</c-><c- n="">f</c-><c- p="">,</c-> <c- mi="">1</c-><c- p="">,</c-> <c- mi="">0</c-><c- p="">)</c-> <c- p="">);</c-> <c- c1="">// x = 0, returns 1</c->
</pre>
   <p>This would allow directly testing contracts without violating those contracts.
The tests would be very fast (no throws or terminates involved), and low maintenance.</p>
   <p>To the author’s knowledge, no such facility is currently proposed.
This reflection utility has applications beyond testing, such as 
automatically generating "wide" wrapper functions from "narrow" 
functions.
This strawman proposal doesn’t address core-language asserts.</p>
   <h5 class="heading settled" data-level="8.4.1.3" id="contracts_change_noexcept"><span class="secno">8.4.1.3. </span><span class="content">Allow contract build modes to change the behavior of <code class="highlight"><c- k="">noexcept</c-></code></span><a class="self-link" href="#contracts_change_noexcept"></a></h5>
    Perhaps we consider <code class="highlight"><c- k="">noexcept</c-></code> the first core-language contract, with a default violation handler of <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">terminate</c-></code>.
The <code class="highlight"><c- n="">Eval_and_throw</c-></code> mode could change the behavior of <code class="highlight"><c- k="">noexcept</c-></code> to observe exceptions instead of <code class="highlight"><c- n="">terminate</c-></code>. 
   <p>This may even be something that should be extended to a general sad-path post-condition checking facility.
It would be nice if we could express that, on failure, <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">vector</c-></code>’s single element insert should leave the container with the same <code class="highlight"><c- n="">size</c-><c- p="">()</c-></code>, and the same <code class="highlight"><c- n="">data</c-><c- p="">()</c-></code> pointer.
Making such sad-path post-condition checks throw on failure would also lead to early termination.</p>
   <p>Allowing contract build modes to change the behavior of <code class="highlight"><c- k="">noexcept</c-></code> could be a concise way to unify <code class="highlight"><c- k="">noexcept</c-></code> and core-language contracts, but it could come at a substantial compatibility cost for those using core-language contracts.
If their code was relying on <code class="highlight"><c- k="">noexcept</c-></code> terminating, then enabling <code class="highlight"><c- n="">Eval_and_throw</c-></code> will break their program.</p>
   <p>This approach may be able to be combined with <a href="#magic_ub_exception">§ 8.4.7.2 Exploiting precondition undefined behavior to ignore termination</a> to avoid major compatibility breaks.</p>
   <h4 class="heading settled" data-level="8.4.2" id="extract_contracts_to_function"><span class="secno">8.4.2. </span><span class="content">Extract contract predicates to a function</span><a class="self-link" href="#extract_contracts_to_function"></a></h4>
    A user could emulate the precondition reflection by following a good naming convention. 
<pre class="language-c++ highlight"><c- b="">bool</c-> <c- nf="">precondition_f</c-><c- p="">(</c-><c- b="">int</c-> <c- n="">x</c-><c- p="">)</c-> <c- n="">noexcept</c-><c- p="">;</c->
<c- b="">bool</c-> <c- nf="">postcondition_f</c-><c- p="">(</c-><c- b="">int</c-> <c- n="">retval</c-><c- p="">,</c-> <c- b="">int</c-> <c- n="">x</c-><c- p="">)</c-> <c- n="">noexcept</c-><c- p="">;</c->
<c- b="">int</c-> <c- nf="">f</c-><c- p="">(</c-><c- b="">int</c-> <c- n="">x</c-><c- p="">)</c-> <c- n="">noexcept</c-> <c- p="">{</c->
  <c- n="">assert</c-><c- p="">(</c-><c- n="">precondition_f</c-><c- p="">(</c-><c- n="">x</c-><c- p="">));</c->
  <c- b="">int</c-> <c- n="">retval</c-> <c- o="">=</c-> <c- mi="">0</c-><c- p="">;</c->
  <c- d="">/*...*/</c->
  <c- n="">assert</c-><c- p="">(</c-><c- n="">postcondition_f</c-><c- p="">(</c-><c- n="">retval</c-><c- p="">,</c-> <c- n="">x</c-><c- p="">));</c->
  <c- k="">return</c-> <c- n="">retval</c-><c- p="">;</c->
<c- p="">}</c->

<c- n="">EXPECT_TRUE</c-><c- p="">(</c->  <c- n="">precondition_f</c-><c- p="">(</c-><c- mi="">20</c-><c- p="">)</c-> <c- p="">);</c->
<c- n="">EXPECT_FALSE</c-><c- p="">(</c-> <c- n="">precondition_f</c-><c- p="">(</c-><c- mi="">-1</c-><c- p="">)</c-> <c- p="">);</c->
<c- n="">EXPECT_TRUE</c-><c- p="">(</c->  <c- n="">postcondition_f</c-><c- p="">(</c-><c- mi="">2</c-><c- p="">,</c-> <c- mi="">20</c-><c- p="">)</c-> <c- p="">);</c->
<c- n="">EXPECT_FALSE</c-><c- p="">(</c-> <c- n="">postcondition_f</c-><c- p="">(</c-><c- mi="">1</c-><c- p="">,</c-> <c- mi="">0</c-><c- p="">)</c-> <c- p="">);</c->
</pre>
   <p>This is an approach that is available for today’s precondition and
 post-condition checking facilities.
A sophisticated user could write static analysis checks to enforce such a
 convention.
The author is unaware of any libraries or guidelines that do this 
though, which suggests that users either didn’t think of it, or they 
don’t see this approach as a good return on investment.</p>
   <h4 class="heading settled" data-level="8.4.3" id="throwing_not_used_by_big_impls"><span class="secno">8.4.3. </span><span class="content">The widely deployed implementations don’t diagnose contract violations with exceptions</span><a class="self-link" href="#throwing_not_used_by_big_impls"></a></h4>
    <a data-link-type="biblio" href="#biblio-berg1656" title="P1656R2, &quot;Throws: Nothing&quot; should be noexcept">[Bergé1656]</a>, <a data-link-type="biblio" href="#biblio-doumler2831" title="P2831R0, Functions having a narrow contract should not be noexcept">[Doumler2831]</a> 
   <p>In 2023, the three most widely deployed standard libraries are 
libc++ (shipping with Clang), libstdc++ (shipping with GCC), and 
Microsoft’s Visual Studio standard library (shipping with Microsoft 
Visual Studio).
None of these implementations use exceptions to diagnose contract 
violations.</p>
   <h4 class="heading settled" data-level="8.4.4" id="noexcept_macro"><span class="secno">8.4.4. </span><span class="content"><code class="highlight"><c- k="">noexcept</c-></code> macro</span><a class="self-link" href="#noexcept_macro"></a></h4>
    <a data-link-type="biblio" href="#biblio-meredithn3248" title="N3248, noexcept Prevents Library Validation">[MeredithN3248]</a>, <a data-link-type="biblio" href="#biblio-doumler2831" title="P2831R0, Functions having a narrow contract should not be noexcept">[Doumler2831]</a> 
   <p>Libraries can define a macro like the following:</p>
<pre class="language-c++ highlight"><c- cp="">#if TEST_ASSERTIONS</c->
  <c- cp="">#define MY_NOEXCEPT</c->
<c- cp="">#else</c->
  <c- cp="">#define MY_NOEXCEPT noexcept</c->
<c- cp="">#endif</c->
</pre>
   <p>This approach works, but it requires a large number of 
annotations.
Switching between the modes is detectable and increases the number of 
differences between the test environment and production environment.
Each difference between test and production decreases the value of the 
test.</p>
   <h4 class="heading settled" data-level="8.4.5" id="setjmp_longjmp"><span class="secno">8.4.5. </span><span class="content">setjmp/longjmp</span><a class="self-link" href="#setjmp_longjmp"></a></h4>
    <a data-link-type="biblio" href="#biblio-meredithn3248" title="N3248, noexcept Prevents Library Validation">[MeredithN3248]</a>, <a data-link-type="biblio" href="#biblio-doumler2831" title="P2831R0, Functions having a narrow contract should not be noexcept">[Doumler2831]</a> 
   <p><code class="highlight"><c- n="">setjmp</c-></code> and <code class="highlight"><c- n="">longjmp</c-></code> can be used to bypass <code class="highlight"><c- k="">noexcept</c-></code> without triggering termination.
It is very difficult to use <code class="highlight"><c- n="">setjmp</c-></code> and <code class="highlight"><c- n="">longjmp</c-></code> without triggering undefined behavior though.
That makes <code class="highlight"><c- n="">setjmp</c-></code> and <code class="highlight"><c- n="">longjmp</c-></code> generally not viable.</p>
   <h4 class="heading settled" data-level="8.4.6" id="threads_fibers_signals"><span class="secno">8.4.6. </span><span class="content">Child threads, fibers, and signals</span><a class="self-link" href="#threads_fibers_signals"></a></h4>
    <a data-link-type="biblio" href="#biblio-doumler2831" title="P2831R0, Functions having a narrow contract should not be noexcept">[Doumler2831]</a> 
   <p>There are other creative ways to write contract handlers that permit testing while avoiding having an exception run into a <code class="highlight"><c- k="">noexcept</c-></code>. <a data-link-type="biblio" href="#biblio-doumler2831" title="P2831R0, Functions having a narrow contract should not be noexcept">[Doumler2831]</a>
 describes some approaches for using (and leaking) threads that halt on 
failure rather than return.
There’s also a description for how to use fibers / stackful coroutines 
to halt without consuming as many resources as the child thread 
approach.
Finally there’s a signal based approach.
All of these approaches have substantial downsides.
None of these approaches are in wide use to the best of the author’s 
knowledge.</p>
   <h4 class="heading settled" data-level="8.4.7" id="compiler_features"><span class="secno">8.4.7. </span><span class="content">Potentially mitigating compiler features</span><a class="self-link" href="#compiler_features"></a></h4>
   <p>There is the potential to address some of the testability concerns of <code class="highlight"><c- k="">noexcept</c-></code> with compiler extensions.</p>
   <p>These ideas aren’t new.
Some of them have been floating around for more than 10 years.</p>
   <p>The fact that they haven’t been implemented says something.
That something may be "Upstreaming compiler changes is an expensive 
prospect, and outside the capabilities of most organizations."
It may be "I’ll do negative testing in a way that doesn’t require a 
compiler feature."
Or it may be "Negative testing isn’t sufficiently valuable to jump 
through these hoops."
So I’m not entirely sure what the lack of implementations says, but it 
certainly says something.</p>
   <h5 class="heading settled" data-level="8.4.7.1" id="make_noexcept_unchecked"><span class="secno">8.4.7.1. </span><span class="content">Compiler flag that makes <code class="highlight"><c- k="">noexcept</c-></code> unchecked</span><a class="self-link" href="#make_noexcept_unchecked"></a></h5>
    The <code class="highlight"><c- k="">noexcept</c-></code> specifier has two direct effects on the semantics of a program: 
   <ul>
    <li data-md="">
     <p>exceptions leaving a <code class="highlight"><c- k="">noexcept</c-></code> function trigger <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">terminate</c-></code>, and</p>
    </li><li data-md="">
     <p>uses of the <code class="highlight"><c- k="">noexcept</c-></code> operator on expressions with the <code class="highlight"><c- k="">noexcept</c-></code> specifier change.</p>
   </li></ul>
   <p>In theory, a compiler could add a non-conforming extensions that removes the <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">terminate</c-></code> aspects, while keeping the <code class="highlight"><c- k="">noexcept</c-></code> operator aspects.
This would make it easier to test contracts, as then any exceptions could still escape <code class="highlight"><c- k="">noexcept</c-></code> functions.</p>
   <p>In some ways, this is the inverse of <a data-link-type="biblio" href="#biblio-halpern2946" title="P2946R0, A flexible solution to the problems of noexcept">[Halpern2946]</a>. <a data-link-type="biblio" href="#biblio-halpern2946" title="P2946R0, A flexible solution to the problems of noexcept">[Halpern2946]</a> proposes a new attribute that (conditionally) keeps the <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">terminate</c-></code> semantics, but doesn’t modify the <code class="highlight"><c- k="">noexcept</c-></code> operator’s behavior.</p>
   <h5 class="heading settled" data-level="8.4.7.2" id="magic_ub_exception"><span class="secno">8.4.7.2. </span><span class="content">Exploiting precondition undefined behavior to ignore termination</span><a class="self-link" href="#magic_ub_exception"></a></h5>
    If a function does not meet its preconditions, then it is not required to meet its post-conditions.
A post-condition of <code class="highlight"><c- k="">noexcept</c-></code> functions is terminating when there’s an exception.
An implementation could, conformingly, bypass the termination aspect of <code class="highlight"><c- k="">noexcept</c-></code> if the program has encountered undefined behavior.
In practice, this may be done by having a "magic" exception type (e.g. <code class="highlight"><c- n="">nonstd</c-><c- o="">::</c-><c- n="">undefined_behavior_exception</c-></code>) that bypasses <code class="highlight"><c- k="">noexcept</c-></code>.
Users would then be required to only use that exception when undefined behavior has been encountered. 
   <h4 class="heading settled" data-level="8.4.8" id="death_tests"><span class="secno">8.4.8. </span><span class="content">Death tests</span><a class="self-link" href="#death_tests"></a></h4>
    <a data-link-type="biblio" href="#biblio-berg1656" title="P1656R2, &quot;Throws: Nothing&quot; should be noexcept">[Bergé1656]</a>, <a data-link-type="biblio" href="#biblio-doumler2831" title="P2831R0, Functions having a narrow contract should not be noexcept">[Doumler2831]</a> 
   <p>A commonly recommended approach for negative testing is to use 
"Death tests".
With death testing, the code under test is run in a different process.
When the code under test executes a failing contract check, the code 
under test is expected to exit abnormally.
The exit value of the child process is checked in the parent process to 
ensure that the contract check was triggered appropriately.
Multiple standard libraries use death tests for their negative testing.</p>
   <p>The largest complaint regarding death testing is the performance 
penalty.
Launching a process is orders of magnitude more expensive than throwing 
an exception, and this can inflate test times from seconds to minutes 
when large numbers of negative tests are present.
The performance penalty is particularly large on Microsoft Windows.</p>
   <p>Traditionally, death tests can communicate a very limited amount 
of information from the child process to the parent process, typically 
one integer or less.
This makes it difficult to know whether the child process’s abnormal 
termination was from the intended contract check failure, or some other 
reason.
In theory, the failing checks could communicate through some other 
out-of-band channel (a file on disk, standard out / error, shared 
memory), but this isn’t currently common practice.</p>
   <p>Launching child processes has other hazards as well.
Using the POSIX <code class="highlight"><c- n="">fork</c-><c- p="">()</c-></code> call while code under test is running in another thread introduces substantial testing risks and uncertainty.
If the code under test is not <code class="highlight"><c- n="">fork</c-><c- p="">()</c-></code> safe, then death tests can’t be launched with <code class="highlight"><c- n="">fork</c-><c- p="">()</c-></code> while the code under test is running.
This can add yet-another performance penalty, as it forces the test to re-run potentially expensive setup code.
The test framework and code under test also have to take care not to run <code class="highlight"><c- n="">fork</c-><c- p="">()</c-></code> unsafe code, which can be challenging when global constructors are involved.
A mitigation for this is to have a test launcher that is entirely distinct from the code under test. <code class="highlight"><c- n="">spawn</c-><c- p="">()</c-></code> and <code class="highlight"><c- n="">clone</c-><c- p="">()</c-></code> calls can also be used, but with their own draw backs.</p>
   <p>Death tests have portability issues.
C++ can run in a variety of environments, and death tests are mostly 
suited to desktop and server environments.
Implementing death tests in browsers and embedded / microcontroller 
environments would be very challenging, as they typically don’t support 
multiple processes.
In addition, most testing frameworks don’t support death tests, with 
GoogleTest being the main test framework with that support.
GoogleTest mixes the code under test and the test infrastructure in the 
same process(es).</p>
   <h3 class="heading settled" data-level="8.5" id="precondition_exception_in_production"><span class="secno">8.5. </span><span class="content">Using exceptions to diagnose precondition violations in production</span><a class="self-link" href="#precondition_exception_in_production"></a></h3>
   <h4 class="heading settled" data-level="8.5.1" id="throwing_security"><span class="secno">8.5.1. </span><span class="content">Security dangers of throwing exceptions while in an unknown state</span><a class="self-link" href="#throwing_security"></a></h4>
   <p>In security sensitive contexts, running out of contract is very dangerous.
Each instruction executed while out of contract is another opportunity for an attacker to do as they please with the system.
Programs should run as little code as possible after detecting contract violations.
This is typically done by exiting the program as quickly as possible.</p>
   <p>Throwing an exception runs a lot of instructions.
Many of those instructions are indirect code branches, which are particularly dangerous.
The Microsoft Visual Studio 32-bit x86 implementation has a build flag (<code class="highlight"><c- o="">/</c-><c- n="">SAFESEH</c-></code>)
 to harden their exception handling implementation against attacks 
attempting to leverage those indirect code branches, but the number of 
instructions run is still very high.</p>
   <h4 class="heading settled" data-level="8.5.2" id="temporary_continuation"><span class="secno">8.5.2. </span><span class="content">Temporary continuation</span><a class="self-link" href="#temporary_continuation"></a></h4>
    <a data-link-type="biblio" href="#biblio-lakos2861" title="P2861R0, The Lakos Rule: Narrow Contracts And noexcept Are Inherently Incompatible">[Lakos2861]</a> 
   <p>Following the narrow <code class="highlight"><c- k="">noexcept</c-></code>
 policy is more permissive in terms of allowing temporary continuation 
than the throws nothing policy.
Some users of C++ desire temporary continuation after contract 
violations, and the throws nothing policy prevents temporary 
continuation in many places.</p>
   <h4 class="heading settled" data-level="8.5.3" id="more_ub_and_noexcept"><span class="secno">8.5.3. </span><span class="content">Likely to cause more UB or hit a destructor <code class="highlight"><c- k="">noexcept</c-></code></span><a class="self-link" href="#more_ub_and_noexcept"></a></h4>
    Writing exception safe code often requires using operations that aren’t allowed to throw.
A common pattern is to "do all the work off to the side, then commit using nonthrowing operations only" <a data-link-type="biblio" href="#biblio-sutter82" title="Exception Safety and Exception Specifications: Are They Worth It?">[Sutter82]</a>.
If one of the non-throwing operations ends up throwing due to a contract
 violation, then additional library UB has been added to the program, 
beyond the initial contract violation. 
   <p>Throwing from a non-throwing operation can also cause termination in destructors, which are <code class="highlight"><c- k="">noexcept</c-></code>
 by default.
So if a contract is violated in a throws nothing function called from a 
destructor, then termination is the behavior, even if continuation is 
the desire.</p>
   <p>Both of these points illustrate the difficulty and danger in 
requiring a program to never terminate, even when aided by throwing 
contract handlers.</p>
   <h4 class="heading settled" data-level="8.5.4" id="garbage_in_garbage_out"><span class="secno">8.5.4. </span><span class="content">Postconditions only hold when preconditions hold</span><a class="self-link" href="#garbage_in_garbage_out"></a></h4>
    <a data-link-type="biblio" href="#biblio-krzemieski2858" title="P2858R0, Noexcept vs contract violations">[Krzemieński2858]</a> 
   <p>A general programming principle is that postconditions aren’t required to hold when preconditions don’t hold.
This is often paraphrased as garbage in, garbage out.
If <code class="highlight"><c- k="">noexcept</c-></code> is a postcondition, then the termination aspect is not required to hold if the precondition doesn’t hold.</p>
   <p><a href="https://godbolt.org/z/36nbY48Er">Here</a> is an example 
program where the violation of a library precondition leads to language 
undefined behavior, with an end result of <code class="highlight"><c- k="">noexcept</c-></code> being bypassed by an exception.</p>
   <h4 class="heading settled" data-level="8.5.5" id="noexcept_contradiction"><span class="secno">8.5.5. </span><span class="content">Precondition UB and <code class="highlight"><c- k="">noexcept</c-></code> contradict?</span><a class="self-link" href="#noexcept_contradiction"></a></h4>
    <a data-link-type="biblio" href="#biblio-doumler2831" title="P2831R0, Functions having a narrow contract should not be noexcept">[Doumler2831]</a> 
   <p><a data-link-type="biblio" href="#biblio-doumler2831" title="P2831R0, Functions having a narrow contract should not be noexcept">[Doumler2831]</a> argues that <code class="highlight"><c- k="">noexcept</c-></code> and precondition undefined behavior contradict, as any behavior should be permitted. <code class="highlight"><c- k="">noexcept</c-></code> prevents the implementer of the function from manifesting some of those behaviors.</p>
   <p>For user code, the extent of their undefined behavior is indeed constrained by <code class="highlight"><c- k="">noexcept</c-></code>.
Standard library implementations are under no such restriction. <a href="#magic_ub_exception">§ 8.4.7.2 Exploiting precondition undefined behavior to ignore termination</a> describes one way that an implementation could choose to throw an exception past <code class="highlight"><c- k="">noexcept</c-></code>, if they deemed it worth the implementation effort.</p>
   <h3 class="heading settled" data-level="8.6" id="termination_risk"><span class="secno">8.6. </span><span class="content">Termination risk</span><a class="self-link" href="#termination_risk"></a></h3>
    <a data-link-type="biblio" href="#biblio-doumler2831" title="P2831R0, Functions having a narrow contract should not be noexcept">[Doumler2831]</a>, <a data-link-type="biblio" href="#biblio-lakos2861" title="P2861R0, The Lakos Rule: Narrow Contracts And noexcept Are Inherently Incompatible">[Lakos2861]</a>, <a data-link-type="biblio" href="#biblio-lakos2949" title="P2949R0, Slides for P2861R0: Narrow Contracts and noexcept are Inherently Incompatable">[Lakos2949]</a> 
   <p>Using <code class="highlight"><c- k="">noexcept</c-></code> can insert code paths that invoke <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">terminate</c-></code>.
The terminating code paths are often unreachable code removed during translation, but this isn’t always the case.</p>
   <p>There are applications that prefer library UB over <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">terminate</c-></code> when faced with a failing contract.
Those libraries may use exceptions to indicate failed contracts.</p>
   <p>For safety critical systems (note the use of the term "systems", 
not applications), undefined behavior is generally considered worse than
 termination, even if the undefined behavior is "only" library UB.
In these systems, an individual application may terminate, but the 
system as a whole has ways to recover from a terminated application, or 
to put the system into a safe state.</p>
   <h3 class="heading settled" data-level="8.7" id="philosphy"><span class="secno">8.7. </span><span class="content">Philosophy</span><a class="self-link" href="#philosphy"></a></h3>
   <h4 class="heading settled" data-level="8.7.1" id="noexcept_accuracy"><span class="secno">8.7.1. </span><span class="content"><code class="highlight"><c- k="">noexcept</c-></code>-accuracy</span><a class="self-link" href="#noexcept_accuracy"></a></h4>
    <a data-link-type="biblio" href="#biblio-berg1656" title="P1656R2, &quot;Throws: Nothing&quot; should be noexcept">[Bergé1656]</a>, <a data-link-type="biblio" href="#biblio-doumler2831" title="P2831R0, Functions having a narrow contract should not be noexcept">[Doumler2831]</a>, <a data-link-type="biblio" href="#biblio-halpern2946" title="P2946R0, A flexible solution to the problems of noexcept">[Halpern2946]</a> 
   <p>There is a desire to document the exception behavior of a function in the signature of that function.
This documentation helps compilers, static analyzers, and people reading the code to understand what the function does.</p>
   <p><a data-link-type="biblio" href="#biblio-krzemieski2858" title="P2858R0, Noexcept vs contract violations">[Krzemieński2858]</a> makes the distinction between functions that can’t throw and functions that can’t fail.
C++'s <code class="highlight"><c- n="">fclose</c-></code> <a href="https://eel.is/c++draft/library#res.on.exception.handling-2">can’t throw</a> (POSIX’s can as part of thread cancellation). <code class="highlight"><c- n="">fclose</c-></code> can fail though, as part of <code class="highlight"><c- n="">fclose</c-></code>
 is flushing buffer contents to storage, and that storage may not be 
available at time of close (imagine a USB drive being removed).</p>
   <p>This separation between can’t throw and can’t fail makes it more difficult to determine what constitutes <code class="highlight"><c- k="">noexcept</c-></code>-accuracy.</p>
   <h4 class="heading settled" data-level="8.7.2" id="can_already_add_noexcept"><span class="secno">8.7.2. </span><span class="content">Doesn’t matter since implementations can already add <code class="highlight"><c- k="">noexcept</c-></code></span><a class="self-link" href="#can_already_add_noexcept"></a></h4>
    <a data-link-type="biblio" href="#biblio-doumler2831" title="P2831R0, Functions having a narrow contract should not be noexcept">[Doumler2831]</a>, <a data-link-type="biblio" href="#biblio-berg1656" title="P1656R2, &quot;Throws: Nothing&quot; should be noexcept">[Bergé1656]</a> 
   <p>If the narrow <code class="highlight"><c- k="">noexcept</c-></code> policy is in place, implementations can strengthen the <code class="highlight"><c- k="">noexcept</c-></code> annotations on their functions.
Major implementations have done so.
Strengthening <code class="highlight"><c- k="">noexcept</c-></code> in the standard would end up adding very few <code class="highlight"><c- k="">noexcept</c-></code> annotations in the major implementations.</p>
   <h4 class="heading settled" data-level="8.7.3" id="stdlib_vs_user_lib_policies"><span class="secno">8.7.3. </span><span class="content">Standard library policies vs. C++ library policies</span><a class="self-link" href="#stdlib_vs_user_lib_policies"></a></h4>
    <a data-link-type="biblio" href="#biblio-lakos2861" title="P2861R0, The Lakos Rule: Narrow Contracts And noexcept Are Inherently Incompatible">[Lakos2861]</a>, <a data-link-type="biblio" href="#biblio-doumler2831" title="P2831R0, Functions having a narrow contract should not be noexcept">[Doumler2831]</a> 
   <p>Many libraries attempt to emulate the design policies of the 
standard library.
The standard library should try to set a good example for third-party 
and end-user libraries, as others will use the standard library as an 
example whether the committee thinks they should or not.</p>
   <p>The standard library needs to accommodate all domains, serve millions of programmers, and billions of users.
Most other libraries aren’t as widely used.
In some libraries, the customers are known well enough that a compatibility hit from changing <code class="highlight"><c- k="">noexcept</c-></code> can be absorbed.
The domain and use cases are known well enough that termination on precondition violation can be deemed suitable.</p>
   <p>For some libraries, improving some performance aspect (like binary
 size) by half a percent is worth increasing the cost of testing by a 
factor of 100.
The more heavily used a library, the more likely it is that such a 
trade-off is worthwhile.
Few libraries are used more heavily than the STL.</p>
   <h4 class="heading settled" data-level="8.7.4" id="impl_strategies_in_the_std"><span class="secno">8.7.4. </span><span class="content">Standard library implementation strategies need not be encoded in the C++ standard</span><a class="self-link" href="#impl_strategies_in_the_std"></a></h4>
    <a data-link-type="biblio" href="#biblio-lakos2861" title="P2861R0, The Lakos Rule: Narrow Contracts And noexcept Are Inherently Incompatible">[Lakos2861]</a> 
   <p>For some standard library implementations, the correct technical 
and business choice is to terminate on precondition failure via a <code class="highlight"><c- k="">noexcept</c-></code>
 decoration.
That is a valid implementation strategy.
However, that doesn’t mean that this implementation should be put in the
 standard, where it constrains other implementations that don’t want to 
make that choice.</p>
   <h4 class="heading settled" data-level="8.7.5" id="cleanup_preconditions"><span class="secno">8.7.5. </span><span class="content">Cleanup operations often have preconditions, and need to not throw</span><a class="self-link" href="#cleanup_preconditions"></a></h4>
    <a data-link-type="biblio" href="#biblio-krzemieski2858" title="P2858R0, Noexcept vs contract violations">[Krzemieński2858]</a> 
   <p>Cleanup operations, like <code class="highlight"><c- k="">delete</c-></code>, <code class="highlight"><c- n="">fclose</c-></code>, and <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">lock_guard</c-><c- o="">::~</c-><c- n="">lock_guard</c-></code> all have preconditions, and all need to be made to not throw.
If the preconditions on these functions were checked and made to throw, they would cause the <code class="highlight"><c- k="">noexcept</c-></code> on destructors to terminate.
If the destructors were marked <code class="highlight"><c- k="">noexcept</c-><c- p="">(</c->false<c- p="">)</c-></code>,
 you would still run the risk of termination from when unwinding 
triggered a precondition fault, causing two exceptions to be active at 
the same time.</p>
   <h4 class="heading settled" data-level="8.7.6" id="invalid_and_indeterminate"><span class="secno">8.7.6. </span><span class="content">Narrow <code class="highlight"><c- k="">noexcept</c-></code> ignores implicit precondition of indeterminate values and invalid objects</span><a class="self-link" href="#invalid_and_indeterminate"></a></h4>
    <a data-link-type="biblio" href="#biblio-lakos2949" title="P2949R0, Slides for P2861R0: Narrow Contracts and noexcept are Inherently Incompatable">[Lakos2949]</a> 
   <p>The narrow <code class="highlight"><c- k="">noexcept</c-></code> policy is defined in terms of wide and narrow contracts, but even the wide contracts have their limits.
Take <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">string</c-><c- o="">::</c-><c- n="">c_str</c-><c- p="">()</c-></code> as an example. <code class="highlight"><c- n="">c_str</c-><c- p="">()</c-></code> is safe to call on any valid <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">string</c-></code>, even the empty string.
However, if the bytes composing the <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">string</c-></code> are corrupted in some way, then <code class="highlight"><c- n="">c_str</c-><c- p="">()</c-></code> is likely to dereference an invalid pointer.
This means that <code class="highlight"><c- n="">c_str</c-><c- p="">()</c-></code> (and most functions) have a precondition of basic object validity.
If wide contracts are expanded to encompass functions that work with invalid objects, then very little has a wide contract.</p>
   <h3 class="heading settled" data-level="8.8" id="narrow_above_throws_nothing"><span class="secno">8.8. </span><span class="content">Can’t write narrow <code class="highlight"><c- k="">noexcept</c-></code> on top of throws nothing</span><a class="self-link" href="#narrow_above_throws_nothing"></a></h3>
    <a data-link-type="biblio" href="#biblio-meredith2837" title="P2837R0, Planning to Revisit the Lakos Rule">[Meredith2837]</a> 
   <p>If part of a system is written with a throws nothing policy, then the system as a whole loses the narrow <code class="highlight"><c- k="">noexcept</c-></code> property.</p>
   <p>Systems built with libc++, libstdc++, and the Microsoft Visual Studio standard library generally do not have the narrow <code class="highlight"><c- k="">noexcept</c-></code> property.</p>
   <p>Other libraries can get many of the benefits of narrow <code class="highlight"><c- k="">noexcept</c-></code>, even if the system as a whole doesn’t have the narrow <code class="highlight"><c- k="">noexcept</c-></code> property.
Negative testing can be performed on narrow <code class="highlight"><c- k="">noexcept</c-></code> libraries, as exceptions usually don’t need to travel far.
Preconditions can be checked in production for all the code between entry points and the first non-narrow <code class="highlight"><c- k="">noexcept</c-></code> code.
Non-narrow <code class="highlight"><c- k="">noexcept</c-></code> libraries that interact heavily with callbacks can get in the way of both precondition checking and negative testing.</p>
   <h2 class="heading settled" data-level="9" id="notable_omissions"><span class="secno">9. </span><span class="content">Notable Omissions</span><a class="self-link" href="#notable_omissions"></a></h2>
    This paper’s discussions focus almost entirely on rule "b" in the <code class="highlight"><c- k="">noexcept</c-></code>
 policy.
The rationale for the other rules haven’t been explored nearly as much.
Given that, I will list some known issues that should be considered 
unaddressed, should someone decide to challenge the other rules. 
   <h3 class="heading settled" data-level="9.1" id="async_callbacks"><span class="secno">9.1. </span><span class="content">Asynchronous callbacks</span><a class="self-link" href="#async_callbacks"></a></h3>
    <a data-link-type="biblio" href="#biblio-stdexec2300" title="P2300R7: std::execution">[StdExec2300]</a> uses the <code class="highlight"><c- k="">noexcept</c-></code>
 operator in conjunction with concepts to make compile-time decisions.
The proposed policies do not place any requirements on concepts or user 
facilities, but the policies do place restrictions on functions.
Many <a data-link-type="biblio" href="#biblio-stdexec2300" title="P2300R7: std::execution">[StdExec2300]</a> functions are marked <code class="highlight"><c- k="">noexcept</c-></code>, but it is unclear to the author of this paper whether any of those functions have preconditions. 
   <p>This paper does not attempt to craft policy regarding <code class="highlight"><c- k="">noexcept</c-></code> and asynchronous callbacks.</p>
   <h3 class="heading settled" data-level="9.2" id="throwing_destructors"><span class="secno">9.2. </span><span class="content">Throwing destructors</span><a class="self-link" href="#throwing_destructors"></a></h3>
    Destructors that <code class="highlight"><c- k="">throw</c-></code> exceptions are uncommon, and usually a bad idea.
However, there are some categories of objects where doing so is useful, like <code class="highlight"><c- n="">scope_success</c-></code> in the library fundamentals v3 TS <a data-link-type="biblio" href="#biblio-lfts4948" title="N4948: Working Draft, C++ Extensions for Library Fundamentals, Version 3">[LFTS4948]</a>. 
   <p>This paper does not attempt to craft policy that distinguishes when having a throwing destructor is acceptable.</p>
   <h3 class="heading settled" data-level="9.3" id="pervasive_conditional"><span class="secno">9.3. </span><span class="content">Pervasive conditional <code class="highlight"><c- k="">noexcept</c-></code></span><a class="self-link" href="#pervasive_conditional"></a></h3>
    Some library authors have expressed desires to standardize conditional <code class="highlight"><c- k="">noexcept</c-></code> operations for facilities like duration math in <code class="highlight"><c- n="">chrono</c-></code>. <code class="highlight"><c- n="">chrono</c-><c- o="">::</c-><c- n="">duration</c-></code>
 instantiations involving built in integers have many non-throwing wide 
contract operations that become throwing when using "BigNum" types. 
   <p>The proposed policies prohibit standardizing conditional <code class="highlight"><c- k="">noexcept</c-></code> for functions other than some special member functions.
This paper provides no rationale for this choice.</p>
   <h3 class="heading settled" data-level="9.4" id="c_compat"><span class="secno">9.4. </span><span class="content">C compatibility</span><a class="self-link" href="#c_compat"></a></h3>
    The proposed policy permits C compatibility facilities to be marked unconditionally noexcept.
This paper provides no rationale for this choice. 
   <h2 class="heading settled" data-level="10" id="principled_design"><span class="secno">10. </span><span class="content">Principled design</span><a class="self-link" href="#principled_design"></a></h2>
    <a data-link-type="biblio" href="#biblio-lakos3004" title="P3004R0, Principled Design for WG21">[Lakos3004]</a>
 describes a process of enumerating, ranking, and scoring design 
principles as a way to aid decision making and communication.  The 
associated paper <a data-link-type="biblio" href="#biblio-lakos3005" title="P3005R0, Memorializing Principled-Design Policies for WG21">[Lakos3005]</a> includes a worked version discussing <code class="highlight"><c- k="">noexcept</c-></code>
 policy variations.  This paper will present an alternative compliance 
table, as well as discuss some of the big differences between the <a data-link-type="biblio" href="#biblio-lakos3005" title="P3005R0, Memorializing Principled-Design Policies for WG21">[Lakos3005]</a> table, and the one presented here. 
   <h3 class="heading settled" data-level="10.1" id="principle_descriptions"><span class="secno">10.1. </span><span class="content">Principle descriptions</span><a class="self-link" href="#principle_descriptions"></a></h3>
   <h4 class="heading settled" data-level="10.1.1" id="shared_principle_descriptions"><span class="secno">10.1.1. </span><span class="content">Shared principles</span><a class="self-link" href="#shared_principle_descriptions"></a></h4>
    The following principles are shared between [[Lakos3005] and this paper, though the wording may be slightly modified. 
   <ul>
    <li data-md="">
     <p>AlgoOpt: Maximize algorithmic runtime optimizations. <a href="#algorithmic_optimizations">§ 8.1 Algorithmic optimizations and exception safety</a></p>
    </li><li data-md="">
     <p>MinExeSize: Minimize executable and shared library size. <a href="#size_bloat">§ 8.3.3 Bloat</a></p>
    </li><li data-md="">
     <p>MinObjSize: Minimize object-code size. <a href="#size_bloat">§ 8.3.3 Bloat</a></p>
    </li><li data-md="">
     <p>MaxExpressInCode: Maximize expressing defined behavior directly in code and the standard. <a href="#noexcept_accuracy">§ 8.7.1 noexcept-accuracy</a></p>
    </li><li data-md="">
     <p>MinUnintendedExit: Minimize the chance that a propagated exception will cause unintended termination. <a href="#termination_risk">§ 8.6 Termination risk</a></p>
    </li><li data-md="">
     <p>MaxNegUnitTest: Maximize the return on investment for negative unit testing of standard functions. <a href="#library_testing">§ 8.4 Library Testing</a></p>
    </li><li data-md="">
     <p>MinCostToImpls: Minimize effort for implementations to remain conformant while satisfying their client base.</p>
    </li><li data-md="">
     <p>MinCostToFixStd: Minimize effort to align the current Standard Library with this policy statement.</p>
    </li><li data-md="">
     <p>MinPermDiverge: Minimize likely persistent discrepancies between the Standard and this policy statement.</p>
    </li><li data-md="">
     <p>MaxUserPortability: Maximize portability for user code written using the Standard Library.</p>
   </li></ul>
   <h4 class="heading settled" data-level="10.1.2" id="new_principle_descriptions"><span class="secno">10.1.2. </span><span class="content">New principles</span><a class="self-link" href="#new_principle_descriptions"></a></h4>
   <p>The following principles are new in this paper.</p>
   <ul>
    <li data-md="">
     <p>TableBasedPerf: Maximize runtime performance on table based implementations. <a href="#modern_impls">§ 8.3.1 "Modern" implementations</a></p>
    </li><li data-md="">
     <p>NonTablePerf: Maximize runtime performance on non-table based implementations. <a href="#other_impls">§ 8.3.2 Other implementations</a></p>
    </li><li data-md="">
     <p>MinUnsafe: Minimize utility of unsafe, insecure, and misleading patterns. <a href="#throwing_security">§ 8.5.1 Security dangers of throwing exceptions while in an unknown state</a>, <a href="#more_ub_and_noexcept">§ 8.5.3 Likely to cause more UB or hit a destructor noexcept</a></p>
    </li><li data-md="">
     <p>FutureWidening: Maximize committee’s ability to widen function contracts in the future <a href="#backwards_compat">§ 8.2 Narrow to wide substitutability / backwards compatibility</a></p>
    </li><li data-md="">
     <p>MaxContractRecovery: Maximize user’s ability to recover from a contract violation without terminating <a href="#temporary_continuation">§ 8.5.2 Temporary continuation</a>, <a href="#termination_risk">§ 8.6 Termination risk</a></p>
   </li></ul>
   <h4 class="heading settled" data-level="10.1.3" id="omitted_principle_descriptions"><span class="secno">10.1.3. </span><span class="content">Omitted principles</span><a class="self-link" href="#omitted_principle_descriptions"></a></h4>
   <p>The following principles from <a data-link-type="biblio" href="#biblio-lakos3005" title="P3005R0, Memorializing Principled-Design Policies for WG21">[Lakos3005]</a> are not scored or ranked in this paper.</p>
   <ul>
    <li data-md="">
     <p>ArgRestrict: Maximize use of noexcept to qualify function parameters.</p>
    </li><li data-md="">
     <p>AllowOnAsyncFrame: Allow noexcept on customization-point functions used in asynchronous contexts.</p>
   </li></ul>
   <p>These principles seem to be related to questions involving asynchronous callbacks.
This paper is choosing to not address asynchronous callback noexcept questions at this time. <a href="#async_callbacks">§ 9.1 Asynchronous callbacks</a></p>
   <ul>
    <li data-md="">
     <p>MaxUserSafeShut: Maximize implementations’ ability to enable users to achieve safe shutdown in production.</p>
    </li><li data-md="">
     <p>MaxUserSafeRecov: Maximize implementations’ ability to enable users to handle and continuing in production.</p>
   </li></ul>
   <p>These principles are replaced by MaxContractRecovery.</p>
   <p>In addition, these principles conflate safety, shutting down cleanly, and recovery with throwing contract-violation handlers.</p>
   <p>If future revisions of this paper are needed, then more detailed 
arguments about safe shutdown and safe continuation can be provided. <a href="#precondition_exception_in_production">§ 8.5 Using exceptions to diagnose precondition violations in production</a> contains some discussion.</p>
   <ul>
    <li data-md="">
     <p>MaxImplFlexHand: Maximize implementations’ ability to support throwing contract-violation handlers.</p>
   </li></ul>
   <p>This principle is replaced by MaxContractRecovery.</p>
   <p>MaxImplFlexHand isn’t directly useful.
If a contract-violation handler throws, and almost immediately terminates due to it hitting a <code class="highlight"><c- k="">noexcept</c-></code>, then that is operating as specified, and therefore easy to support.
MaxContractRecovery attempts to capture the use case of contract failures being recoverable.</p>
   <ul>
    <li data-md="">
     <p>MaxBestPracExamp: Maximize a desirable best-practices model (safety/performance) for typical retail users.</p>
   </li></ul>
   <p><a href="#stdlib_vs_user_lib_policies">§ 8.7.3 Standard library policies vs. C++ library policies</a>
 discusses the topic.
Scoring this topic is challenging, as what constitutes the best practice
 is up for debate.
This means that the scoring for such a policy is circular, in that we 
need to know the solution outcome to know a proper score for the 
principle.
As a result, I chose not to score this policy.</p>
   <ul>
    <li data-md="">
     <p>MaxUseForAlgoNeed: Maximize ability to use noexcept for narrow contracts having algorithmic need.</p>
   </li></ul>
   <p>This seems like a duplicate of AlgoOpt "Maximize algorithmic runtime optimizations".</p>
   <ul>
    <li data-md="">
     <p>MinDivergMeaning: Minimize divergence in meaning of standard functions across conforming implementations.</p>
   </li></ul>
   <p>This seems to be a duplicate of MaxUserPortabilty "Maximize portability for user code written using the Standard Library".
Divergence in behavior causes portability issues.</p>
   <ul>
    <li data-md="">
     <p>MaxMultiverse: Minimize the likelihood of disenfranchising a member of the multiverse. <a href="#narrow_above_throws_nothing">§ 8.8 Can’t write narrow noexcept on top of throws nothing</a></p>
   </li></ul>
   <p>This is more of a meta-principle.
This meta-principle encourages prioritizing cutting solutions with low 
principle scores, even when a given solution may win out on more 
important principles.</p>
   <h3 class="heading settled" data-level="10.2" id="solution_descriptions"><span class="secno">10.2. </span><span class="content">Solution descriptions</span><a class="self-link" href="#solution_descriptions"></a></h3>
    This paper describes two solutions, but represents it as three columns in the compliance table.
The narrow <code class="highlight"><c- k="">noexcept</c-></code> solution is represented twice, once for the "minority" implementations that only use <code class="highlight"><c- k="">noexcept</c-></code> where mandated by the standard, and once for the "majority" implementations that place <code class="highlight"><c- k="">noexcept</c-></code> on most functions that throw nothing (as permitted by the standard).
This will allow readers to gauge the impact in the different implementations. 
   <ul>
    <li data-md="">
     <p>MinNar: Minority narrow <code class="highlight"><c- k="">noexcept</c-></code>.  The minority implementations place <code class="highlight"><c- k="">noexcept</c-></code> only where required.</p>
    </li><li data-md="">
     <p>MajNar: Majority narrow <code class="highlight"><c- k="">noexcept</c-></code>.  These implementations place <code class="highlight"><c- k="">noexcept</c-></code> on most "throws nothing" functions.  Closest to status quo.</p>
    </li><li data-md="">
     <p>TN: Throws nothing rule</p>
   </li></ul>
   <p>Most of the standard library is specified using the narrow <code class="highlight"><c- k="">noexcept</c-></code>
 design principle.
It _almost_ counts as the status quo policy.
However,  we currently don’t have a formal policy.
This no-policy status quo is not represented in the table, as it is very
 difficult to reason about the properties of an "anything goes" 
approach.
This is one of the reasons the author would prefer _a_ policy, even if 
it is not the author’s preferred policy.</p>
   <p>MinNar and MajNar correspond to solution C (MAX+LAK+NLC) in <a data-link-type="biblio" href="#biblio-lakos3005" title="P3005R0, Memorializing Principled-Design Policies for WG21">[Lakos3005]</a>.
TN corresponds to solution B (MAX) in <a data-link-type="biblio" href="#biblio-lakos3005" title="P3005R0, Memorializing Principled-Design Policies for WG21">[Lakos3005]</a>.</p>
   <p>The author did not have the time to apply the principled design approach to the large variety of options explored in <a data-link-type="biblio" href="#biblio-lakos3005" title="P3005R0, Memorializing Principled-Design Policies for WG21">[Lakos3005]</a>.  There’s only so much time between the February 2024 mailing and the 2024 March Tokyo meeting.</p>
   <h3 class="heading settled" data-level="10.3" id="compliance_table"><span class="secno">10.3. </span><span class="content">Compliance table</span><a class="self-link" href="#compliance_table"></a></h3>
   <table>
    <tbody>
     <tr>
      <th>Rank
      </th><th>Importance
      </th><th>Objectivity
      </th><th>Principle ID
      </th><th>MinNar
      </th><th>MajNar
      </th><th>TN
     </th></tr><tr>
      <td>1
      </td><td>9
      </td><td>@
      </td><td>AlgoOpt
      </td><td>9
      </td><td>9
      </td><td>9
     </td></tr><tr>
      <td>2
      </td><td>9
      </td><td>9
      </td><td>TableBasedPerf
      </td><td>9
      </td><td>9
      </td><td>9
     </td></tr><tr>
      <td>3
      </td><td>5
      </td><td>9
      </td><td>NonTablePerf
      </td><td>5
      </td><td>9
      </td><td>9
     </td></tr><tr>
      <td>4
      </td><td>5
      </td><td>9
      </td><td>MinExeSize
      </td><td>5
      </td><td>9
      </td><td>9
     </td></tr><tr>
      <td>5
      </td><td>5
      </td><td>5
      </td><td>MaxExpressInCode
      </td><td>3
      </td><td>5
      </td><td>7
     </td></tr><tr>
      <td>6
      </td><td>5
      </td><td>5
      </td><td>MaxUserPortability
      </td><td>7
      </td><td>7
      </td><td>9
     </td></tr><tr>
      <td>7
      </td><td>5
      </td><td>5
      </td><td>MinUnintendedExit
      </td><td>7
      </td><td>5
      </td><td>5
     </td></tr><tr>
      <td>8
      </td><td>5
      </td><td>5
      </td><td>MaxNegUnitTest
      </td><td>7
      </td><td>3
      </td><td>3
     </td></tr><tr>
      <td>9
      </td><td>5
      </td><td>5
      </td><td>MinUnsafe
      </td><td>3
      </td><td>7
      </td><td>7
     </td></tr><tr>
      <td>10
      </td><td>5
      </td><td>-
      </td><td>MinCostToImpls
      </td><td>9
      </td><td>9
      </td><td>7
     </td></tr><tr>
      <td>11
      </td><td>1
      </td><td>5
      </td><td>FutureWidening
      </td><td>5
      </td><td>5
      </td><td>3
     </td></tr><tr>
      <td>12
      </td><td>1
      </td><td>5
      </td><td>MaxContractRecovery
      </td><td>7
      </td><td>3
      </td><td>3
     </td></tr><tr>
      <td>13
      </td><td>1
      </td><td>-
      </td><td>MinCostToFixStd
      </td><td>7
      </td><td>3
      </td><td>3
     </td></tr><tr>
      <td>14
      </td><td>1
      </td><td>-
      </td><td>MinPermDiverge
      </td><td>7
      </td><td>3
      </td><td>3
     </td></tr><tr>
      <td>15
      </td><td>-
      </td><td>9
      </td><td>MinObjSize
      </td><td>5
      </td><td>9
      </td><td>9
   </td></tr></tbody></table>
   <h3 class="heading settled" data-level="10.4" id="differences_with_lakos"><span class="secno">10.4. </span><span class="content">Comparison with <a data-link-type="biblio" href="#biblio-lakos3005" title="P3005R0, Memorializing Principled-Design Policies for WG21">[Lakos3005]</a></span><a class="self-link" href="#differences_with_lakos"></a></h3>
    Many of the scores for the solutions differed by small amounts in the papers.
Small, 2 point changes won’t be elaborated on here except where it moves a score away from 1. 
   <p><a data-link-type="biblio" href="#biblio-lakos3005" title="P3005R0, Memorializing Principled-Design Policies for WG21">[Lakos3005]</a> places an importance of 9 on the MaxImplFlexHand, MaxUserSafeShut, and MaxUserSafeRecov policies.
This paper gives MaxContractRecovery an importance of 1.</p>
   <p>This paper places a higher importance on MinExeSize than <a data-link-type="biblio" href="#biblio-lakos3005" title="P3005R0, Memorializing Principled-Design Policies for WG21">[Lakos3005]</a> (importance 5 vs. 1).
Time and space efficiency have always been key concerns of C++, even in the Design &amp; Evolution <a data-link-type="biblio" href="#biblio-stroustrupde" title="The Design and Evolution of C++">[StroustrupDE]</a> days.</p>
   <p>This paper scores MinUnintenedExit much higher for both policies.
Very little standard library code that invokes user code would be marked <code class="highlight"><c- k="">noexcept</c-></code> with either policy, so the <a data-link-type="biblio" href="#biblio-lakos3005" title="P3005R0, Memorializing Principled-Design Policies for WG21">[Lakos3005]</a> scores of 1 and 3 seem unwarranted. <code class="highlight"><c- k="">noexcept</c-></code> on destructors and <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- kr="">thread</c-></code> are going to be very common causes of unintended exits, and their behaviors are the same in this paper and <a data-link-type="biblio" href="#biblio-lakos3005" title="P3005R0, Memorializing Principled-Design Policies for WG21">[Lakos3005]</a>.</p>
   <p>MaxNegUnitTest is higher in importance here (5 vs. 1).
The scores are also closer together.
Negative testing is possible with the throws nothing policy, though they
 are more expensive.
The return on investment for negative testing with narrow noexcept isn’t
 ideal, as it requires using the very slow exception sad path.</p>
   <h2 class="heading settled" data-level="11" id="suggested_polls"><span class="secno">11. </span><span class="content">Suggested polls</span><a class="self-link" href="#suggested_polls"></a></h2>
   <h3 class="heading settled" data-level="11.1" id="better_than_nothing_poll"><span class="secno">11.1. </span><span class="content">Either policy is better than no policy</span><a class="self-link" href="#better_than_nothing_poll"></a></h3>
   <blockquote>
    <p><b>Poll:</b> Having one of the two proposed <code class="highlight"><c- k="">noexcept</c-></code>
 policies in place is more important than having my preferred policy, so
 a head-to-head poll between the two presented alternatives is an 
acceptable way to select the policy.<br></p>
    <p>5-way poll (SF/WF/N/WA/SA)<br></p>
   </blockquote>
   <p>If the "any policy" poll gains consensus, then we do a head-to-head poll on the policies.</p>
   <p>If the "any policy" poll does not gain consensus, then we do two 5 way polls.
Whichever poll has consensus in general, and has more consensus than the other, wins.
It is possible that neither has consensus.
If LEWG is a little crazy, then both may have consensus.</p>
   <p>If we do these as electronic polls (and we should), then all four polls should run.</p>
   <h3 class="heading settled" data-level="11.2" id="head_to_head_poll"><span class="secno">11.2. </span><span class="content">Head-to-head policy poll</span><a class="self-link" href="#head_to_head_poll"></a></h3>
   <blockquote>
    <p><b>Poll:</b> Which policy do we adopt?<br></p>
    <p>3-way poll (narrow <code class="highlight"><c- k="">noexcept</c-></code>/"Lakos rule")/Neutral/"Throws nothing rule"<br></p>
   </blockquote>
   <h3 class="heading settled" data-level="11.3" id="narrow_lakos_poll"><span class="secno">11.3. </span><span class="content">Adopt the narrow <code class="highlight"><c- k="">noexcept</c-></code>/"Lakos rule" <code class="highlight"><c- k="">noexcept</c-></code> policy</span><a class="self-link" href="#narrow_lakos_poll"></a></h3>
   <blockquote>
    <p><b>Poll:</b> Add the narrow <code class="highlight"><c- k="">noexcept</c-></code>/"Lakos rule" <code class="highlight"><c- k="">noexcept</c-></code> policy to SD-9<br></p>
    <p>5-way poll (SF/WF/N/WA/SA)<br></p>
   </blockquote>
   <h3 class="heading settled" data-level="11.4" id="throws_nothing_poll"><span class="secno">11.4. </span><span class="content">Adopt the "Throws nothing rule" <code class="highlight"><c- k="">noexcept</c-></code> policy</span><a class="self-link" href="#throws_nothing_poll"></a></h3>
   <blockquote>
    <p><b>Poll:</b> Add the "Throws nothing rule" <code class="highlight"><c- k="">noexcept</c-></code> policy to SD-9<br></p>
    <p>5-way poll (SF/WF/N/WA/SA)<br></p>
   </blockquote>
   <h2 class="heading settled" data-level="12" id="ack"><span class="secno">12. </span><span class="content">Acknowledgments</span><a class="self-link" href="#ack"></a></h2>
    Thanks to David Sankel for providing wording suggestions. 
  </main>
<script>
(function() {
  "use strict";
  var collapseSidebarText = '<span aria-hidden="true">←</span> '
                          + '<span>Collapse Sidebar</span>';
  var expandSidebarText   = '<span aria-hidden="true">→</span> '
                          + '<span>Pop Out Sidebar</span>';
  var tocJumpText         = '<span aria-hidden="true">↑</span> '
                          + '<span>Jump to Table of Contents</span>';

  var sidebarMedia = window.matchMedia('screen and (min-width: 78em)');
  var autoToggle   = function(e){ toggleSidebar(e.matches) };
  if(sidebarMedia.addListener) {
    sidebarMedia.addListener(autoToggle);
  }

  function toggleSidebar(on) {
    if (on == undefined) {
      on = !document.body.classList.contains('toc-sidebar');
    }

    /* Don't scroll to compensate for the ToC if we're above it already. */
    var headY = 0;
    var head = document.querySelector('.head');
    if (head) {
      // terrible approx of "top of ToC"
      headY += head.offsetTop + head.offsetHeight;
    }
    var skipScroll = window.scrollY < headY;

    var toggle = document.getElementById('toc-toggle');
    var tocNav = document.getElementById('toc');
    if (on) {
      var tocHeight = tocNav.offsetHeight;
      document.body.classList.add('toc-sidebar');
      document.body.classList.remove('toc-inline');
      toggle.innerHTML = collapseSidebarText;
      if (!skipScroll) {
        window.scrollBy(0, 0 - tocHeight);
      }
      tocNav.focus();
      sidebarMedia.addListener(autoToggle); // auto-collapse when out of room
    }
    else {
      document.body.classList.add('toc-inline');
      document.body.classList.remove('toc-sidebar');
      toggle.innerHTML = expandSidebarText;
      if (!skipScroll) {
        window.scrollBy(0, tocNav.offsetHeight);
      }
      if (toggle.matches(':hover')) {
        /* Unfocus button when not using keyboard navigation,
           because I don't know where else to send the focus. */
        toggle.blur();
      }
    }
  }

  function createSidebarToggle() {
    /* Create the sidebar toggle in JS; it shouldn't exist when JS is off. */
    var toggle = document.createElement('a');
      /* This should probably be a button, but appearance isn't standards-track.*/
    toggle.id = 'toc-toggle';
    toggle.class = 'toc-toggle';
    toggle.href = '#toc';
    toggle.innerHTML = collapseSidebarText;

    sidebarMedia.addListener(autoToggle);
    var toggler = function(e) {
      e.preventDefault();
      sidebarMedia.removeListener(autoToggle); // persist explicit off states
      toggleSidebar();
      return false;
    }
    toggle.addEventListener('click', toggler, false);


    /* Get <nav id=toc-nav>, or make it if we don't have one. */
    var tocNav = document.getElementById('toc-nav');
    if (!tocNav) {
      tocNav = document.createElement('p');
      tocNav.id = 'toc-nav';
      /* Prepend for better keyboard navigation */
      document.body.insertBefore(tocNav, document.body.firstChild);
    }
    /* While we're at it, make sure we have a Jump to Toc link. */
    var tocJump = document.getElementById('toc-jump');
    if (!tocJump) {
      tocJump = document.createElement('a');
      tocJump.id = 'toc-jump';
      tocJump.href = '#toc';
      tocJump.innerHTML = tocJumpText;
      tocNav.appendChild(tocJump);
    }

    tocNav.appendChild(toggle);
  }

  var toc = document.getElementById('toc');
  if (toc) {
    createSidebarToggle();
    toggleSidebar(sidebarMedia.matches);

    /* If the sidebar has been manually opened and is currently overlaying the text
       (window too small for the MQ to add the margin to body),
       then auto-close the sidebar once you click on something in there. */
    toc.addEventListener('click', function(e) {
      if(e.target.tagName.toLowerCase() == "a" && document.body.classList.contains('toc-sidebar') && !sidebarMedia.matches) {
        toggleSidebar(false);
      }
    }, false);
  }
  else {
    console.warn("Can't find Table of Contents. Please use <nav id='toc'> around the ToC.");
  }

  /* Wrap tables in case they overflow */
  var tables = document.querySelectorAll(':not(.overlarge) > table.data, :not(.overlarge) > table.index');
  var numTables = tables.length;
  for (var i = 0; i < numTables; i++) {
    var table = tables[i];
    var wrapper = document.createElement('div');
    wrapper.className = 'overlarge';
    table.parentNode.insertBefore(wrapper, table);
    wrapper.appendChild(table);
  }

})();
</script>
  <h2 class="no-num no-ref heading settled" id="references"><span class="content">References</span><a class="self-link" href="#references"></a></h2>
  <h3 class="no-num no-ref heading settled" id="informative"><span class="content">Informative References</span><a class="self-link" href="#informative"></a></h3>
  <dl>
   <dt id="biblio-abrahamsn2983">[AbrahamsN2983]
   </dt><dd>David Abrahams; Rani Sharoni; Douglas Gregor. <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2983.html"><cite>N2983, Allowing Move Constructors to Throw</cite></a>. URL: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2983.html">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2983.html</a>
   </dd><dt id="biblio-berg1656">[Bergé1656]
   </dt><dd>Agustín Bergé. <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1656r2.html"><cite>P1656R2, "Throws: Nothing" should be noexcept</cite></a>. URL: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1656r2.html">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1656r2.html</a>
   </dd><dt id="biblio-cpp2023-12">[Cpp2023-12]
   </dt><dd>Thomas Köppe. <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4971.pdf"><cite>N4971: Working Draft, Programming Languages -- C++</cite></a>. URL: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4971.pdf">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4971.pdf</a>
   </dd><dt id="biblio-craig1640">[Craig1640]
   </dt><dd>Ben Craig. <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1640r1.html"><cite>P1640R1, Error size benchmarking: Redux</cite></a>. URL: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1640r1.html">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1640r1.html</a>
   </dd><dt id="biblio-craig1886">[Craig1886]
   </dt><dd>Ben Craig. <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1886r0.html"><cite>P1886R0, Error speed benchmarking</cite></a>. URL: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1886r0.html">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1886r0.html</a>
   </dd><dt id="biblio-doumler2831">[Doumler2831]
   </dt><dd>Timur Doumler; Ed Catmur. <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2831r0.pdf"><cite>P2831R0, Functions having a narrow contract should not be noexcept</cite></a>. URL: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2831r0.pdf">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2831r0.pdf</a>
   </dd><dt id="biblio-gregorn2855">[GregorN2855]
   </dt><dd>Douglas Gregor; David Abrahams. <a href="https://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2855.html"><cite>N2855, Rvalue References and Exception Safety</cite></a>. URL: <a href="https://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2855.html">https://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2855.html</a>
   </dd><dt id="biblio-halpern2946">[Halpern2946]
   </dt><dd>Pablo Halpern. <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2946r0.pdf"><cite>P2946R0, A flexible solution to the problems of noexcept</cite></a>. URL: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2946r0.pdf">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2946r0.pdf</a>
   </dd><dt id="biblio-johnson2148">[Johnson2148]
   </dt><dd>CJ Johnson; Bryce Adelstein Lelbach. <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2148r0.pdf"><cite>P2148R0, Library Evolution Design Guidelines</cite></a>. URL: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2148r0.pdf">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2148r0.pdf</a>
   </dd><dt id="biblio-josuttis0884">[Josuttis0884]
   </dt><dd>Nicolai Josuttis. <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0884r0.pdf"><cite>P0884R0, Extending the noexcept Policy, Rev0</cite></a>. URL: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0884r0.pdf">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0884r0.pdf</a>
   </dd><dt id="biblio-krzemieski2858">[Krzemieński2858]
   </dt><dd>Andrzej Krzemieński. <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2858r0.html"><cite>P2858R0, Noexcept vs contract violations</cite></a>. URL: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2858r0.html">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2858r0.html</a>
   </dd><dt id="biblio-lakos2861">[Lakos2861]
   </dt><dd>John Lakos. <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2861r0.pdf"><cite>P2861R0, The Lakos Rule: Narrow Contracts And noexcept Are Inherently Incompatible</cite></a>. URL: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2861r0.pdf">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2861r0.pdf</a>
   </dd><dt id="biblio-lakos2949">[Lakos2949]
   </dt><dd>John Lakos. <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2949r0.pdf"><cite>P2949R0, Slides for P2861R0: Narrow Contracts and noexcept are Inherently Incompatable</cite></a>. URL: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2949r0.pdf">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2949r0.pdf</a>
   </dd><dt id="biblio-lakos3004">[Lakos3004]
   </dt><dd>John Lakos, Harold Bott, Mungo Gill, Lori Hughes, Alisdair Meredith, Bill Chapman, Mike Giroux, Oleg Subbotin. <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3004r0.pdf"><cite>P3004R0, Principled Design for WG21</cite></a>. URL: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3004r0.pdf">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3004r0.pdf</a>
   </dd><dt id="biblio-lakos3005">[Lakos3005]
   </dt><dd>John Lakos, Joshua Berne, Harold Bott, Mungo Gill, Alisdair Meredith, Bill Chapman, Mike Giroux, Oleg Subbotin. <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3005r0.pdf"><cite>P3005R0, Memorializing Principled-Design Policies for WG21</cite></a>. URL: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3005r0.pdf">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3005r0.pdf</a>
   </dd><dt id="biblio-lelbach2920">[Lelbach2920]
   </dt><dd>Bryce Adelstein Lelbach; et al. <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2920r0.pdf"><cite>P2920R0, Library Evolution Leadership's Understanding of the Noexcept Policy History</cite></a>. URL: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2920r0.pdf">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2920r0.pdf</a>
   </dd><dt id="biblio-lfts4948">[LFTS4948]
   </dt><dd>Thomas Köppe. <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4948.html"><cite>N4948: Working Draft, C++ Extensions for Library Fundamentals, Version 3</cite></a>. URL: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4948.html">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4948.html</a>
   </dd><dt id="biblio-meredith2837">[Meredith2837]
   </dt><dd>Alisdair Meredith; Harold Bott Jr.. <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2837r0.pdf"><cite>P2837R0, Planning to Revisit the Lakos Rule</cite></a>. URL: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2837r0.pdf">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2837r0.pdf</a>
   </dd><dt id="biblio-meredithn3248">[MeredithN3248]
   </dt><dd>Alisdair Meredith; John Lakos. <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3248.pdf"><cite>N3248, noexcept Prevents Library Validation</cite></a>. URL: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3248.pdf">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3248.pdf</a>
   </dd><dt id="biblio-meredithn3279">[MeredithN3279]
   </dt><dd>Alisdair Meredith; John Lakos. <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3279.pdf"><cite>N3279, Conservative use of noexcept in the Library</cite></a>. URL: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3279.pdf">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3279.pdf</a>
   </dd><dt id="biblio-renwick2019">[Renwick2019]
   </dt><dd>James Renwick; Tom Spink; Björn Franke. <a href="https://www.pure.ed.ac.uk/ws/portalfiles/portal/78829292/low_cost_deterministic_C_exceptions_for_embedded_systems.pdf"><cite>Low-cost deterministic C++ exceptions for embedded systems</cite></a>. URL: <a href="https://www.pure.ed.ac.uk/ws/portalfiles/portal/78829292/low_cost_deterministic_C_exceptions_for_embedded_systems.pdf">https://www.pure.ed.ac.uk/ws/portalfiles/portal/78829292/low_cost_deterministic_C_exceptions_for_embedded_systems.pdf</a>
   </dd><dt id="biblio-stdexec2300">[StdExec2300]
   </dt><dd>Michał Dominiak; et al. <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2300r7.html"><cite>P2300R7: std::execution</cite></a>. URL: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2300r7.html">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2300r7.html</a>
   </dd><dt id="biblio-stroustrupde">[StroustrupDE]
   </dt><dd>Bjarne Stroustrup. <a href="https://www.stroustrup.com/dne.html"><cite>The Design and Evolution of C++</cite></a>. URL: <a href="https://www.stroustrup.com/dne.html">https://www.stroustrup.com/dne.html</a>
   </dd><dt id="biblio-sutter82">[Sutter82]
   </dt><dd>Herb Sutter. <a href="http://www.gotw.ca/gotw/082.htm"><cite>Exception Safety and Exception Specifications: Are They Worth It?</cite></a>. URL: <a href="http://www.gotw.ca/gotw/082.htm">http://www.gotw.ca/gotw/082.htm</a>
   </dd><dt id="biblio-voutilainen2711">[Voutilainen2711]
   </dt><dd>Ville Voutilainen. <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2711r1.html"><cite>P2711R1, Making multi-param constructors of views explicit</cite></a>. URL: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2711r1.html">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2711r1.html</a>
   </dd><dt id="biblio-voutilainen2780">[Voutilainen2780]
   </dt><dd>Ville Voutilainen. <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2780r0.html"><cite>P2780R0, Caller-side precondition checking, and Eval_and_throw</cite></a>. URL: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2780r0.html">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2780r0.html</a>
  </dd></dl></body></html>