<!DOCTYPE html>
<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  
  <meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport">
  <title>P1105R1: Leaving no room for a lower-level language: A C++ Subset</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
 *
 * 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)
 *   - .assertion  for assertions                    (div, p, span)
 *   - .advisement for loud normative statements     (div, p, strong)
 *   - .annoying-warning for spec obsoletion notices (div, aside, details)
 *
 * 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
 *
 * 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)
 *
 ******************************************************************************/

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

	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;

		/* Colors */
		color: black;
		background: white 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-width: .65rem .7rem .6rem;
		border-radius: .4rem;
		background: #1a5e9a;
		color: white;
		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;
		border-color: #c00;
	}

	/* 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: 2;
			bottom: 0; left: 0;
			margin: 0;
			min-width: 1.33em;
			border-top-right-radius: 2rem;
			box-shadow: 0 0 2px;
			font-size: 1.5em;
			color: black;
		}
		#toc-nav > a {
			display: block;
			white-space: nowrap;

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

			background: white;
			box-shadow: 0 0 2px;
			border: none;
			border-top-right-radius: 1.33em;
			background: white;
		}
		#toc-nav > #toc-jump {
			padding-bottom: 2em;
			margin-bottom: -1.9em;
		}

		#toc-nav > a:hover,
		#toc-nav > a:focus {
			background: #f8f8f8;
		}
		#toc-nav > a:not(:hover):not(:focus) {
			color: #707070;
		}

		/* 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-toggle-inline {
			vertical-align: 0.05em;
			font-size: 80%;
			color: gray;
			color: hsla(203,20%,40%,.7);
			border-style: none;
			background: transparent;
			position: relative;
		}
		#toc-toggle-inline:hover:not(:active),
		#toc-toggle-inline:focus:not(:active) {
			text-shadow: 1px 1px silver;
			top: -1px;
			left: -1px;
		}

		#toc-nav :active {
			color: #C00;
		}
	}

/** 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);
			background: inherit;
			background-color: #f7f8f9;
			z-index: 1;
			box-shadow: -.1em 0 .25em rgba(0,0,0,.1) 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);
		}
		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);
			background: inherit;
			background-color: #f7f8f9;
			z-index: 1;
			box-shadow: -.1em 0 .25em rgba(0,0,0,.1) 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);
		}

		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;
		background: transparent;
	}

	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,
	#subtitle {
		/* #subtitle 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) > hr {
		font-size: 1.5em;
		text-align: center;
		margin: 1em auto;
		height: auto;
		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;
	}

	/* Put nice boxes around each algorithm. */
	[data-algorithm]:not(.heading) {
	  padding: .5em;
	  border: thin solid #ddd; 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: medium;
	}
	dfn var {
		font-style: normal;
	}

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

	del { color: red;  text-decoration: line-through; }
	ins { color: #080; text-decoration: underline;    }

/** 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;
		page-break-inside: avoid;
		hyphens: none;
		text-transform: none;
	}
	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;
		text-decoration: none;
		border-bottom: 1px solid #707070;
		/* Need a bit of extending for it to look okay */
		padding: 0 1px 0;
		margin: 0 -1px 0;
	}
	a:visited {
		border-bottom-color: #BBB;
	}

	/* Use distinguishing colors when user is interacting with the link */
	a[href]:focus,
	a[href]:hover {
		background: #f8f8f8;
		background: rgba(75%, 75%, 75%, .25);
		border-bottom-width: 3px;
		margin-bottom: -2px;
	}
	a[href]:active {
		color: #C00;
		border-color: #C00;
	}

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

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

	img {
		border-style: none;
	}

	/* 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;
	}
	.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 {
		padding: .5em;
		border: .5em;
		border-left-style: solid;
		page-break-inside: avoid;
	}
	span.issue, span.note {
		padding: .1em .5em .15em;
		border-right-style: solid;
	}

	.issue,
	.note,
	.example,
	.advisement,
	.assertion,
	blockquote {
		margin: 1em auto;
	}
	.note  > p:first-child,
	.issue > p:first-child,
	blockquote > :first-child {
		margin-top: 0;
	}
	blockquote > :last-child {
		margin-bottom: 0;
	}

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

	blockquote {
		border-color: silver;
	}

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

	.issue {
		border-color: #E05252;
		background: #FBE9E9;
		counter-increment: issue;
		overflow: auto;
	}
	.issue::before, .issue > .marker {
		text-transform: uppercase;
		color: #AE1E1E;
		padding-right: 1em;
		text-transform: uppercase;
	}
	/* 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;
		background: #FCFAEE;
		counter-increment: example;
		overflow: auto;
		clear: both;
	}
	.example::before, .example > .marker {
		text-transform: uppercase;
		color: #827017;
		min-width: 7.5em;
		display: block;
	}
	/* 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;
		background: #E9FBE9;
		overflow: auto;
	}

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

	details.note > summary {
		display: block;
		color: hsl(120, 70%, 30%);
	}
	details.note[open] > summary {
		border-bottom: 1px silver solid;
	}

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

	.assertion {
		border-color: #AAA;
		background: #EEE;
	}

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

	.advisement {
		border-color: orange;
		border-style: none solid;
		background: #FFEECC;
	}
	strong.advisement {
		display: block;
		text-align: center;
	}
	.advisement > .marker {
		color: #B35F00;
	}

/** 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: #fdd;
		color: red;
		font-weight: bold;
		padding: .75em 1em;
		border: thick red;
		border-style: solid;
		border-radius: 1em;
	}
	.annoying-warning :last-child {
		margin-bottom: 0;
	}

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

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

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

	.def {
		padding: .5em 1em;
		background: #DEF;
		margin: 1.2em 0;
		border-left: 0.5em solid #8CCBF2;
	}

/******************************************************************************/
/*                                    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;
	}

	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-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;
		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;
		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-top: 0.1rem;
		/* Larger, more consistently-sized click target */
		display: block;
		/* Reverse color scheme */
		color: black;
		border-color: #3980B5;
		border-bottom-width: 3px !important;
		margin-bottom: 0px !important;
	}
	.toc a:visited {
		border-color: #054572;
	}
	.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;
		line-height: 1.1rem; /* consistent spacing */
	}

	/* 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 .secno { font-size: 85%; }
	.toc > li li li li li { font-size:   85%;    }
	.toc > li li li li li .secno { font-size: 100%; }

	/* @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 {
			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; }
		}
	/* } */

	@supports (display:grid) {
		/* 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;
		}
		#toc .content:hover {
			background: rgba(75%, 75%, 75%, .25);
			border-bottom: 3px solid #054572;
			margin-bottom: -3px;
		}
		#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 span {
			white-space: nowrap;
			color: transparent; }
		ul.index li a:hover + span,
		ul.index li a:focus + span {
			color: #707070;
		}
	}

/** 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]) {
		background: #f7f8f9;
	}

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

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

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

/******************************************************************************/
/*                                    Legacy                                  */
/******************************************************************************/

	/* This rule is inherited from past style sheets. No idea what it's for. */
	.hide { display: none }



/******************************************************************************/
/*                             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 > table {
		/* limit preferred width of table */
		max-width: 50em;
		margin-left: auto;
		margin-right: auto;
	}

	@media (min-width: 55em) {
		.overlarge {
			margin-left: calc(13px + 26.5rem - 50vw);
			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-left: calc(40em - 50vw) !important;
			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-left: 0 !important;
			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 type="text/css">
    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;
    }
  </style>
  <meta content="Bikeshed version e9290f0f6bc01459c8b7bdfa2bb91f6985fc5c67" name="generator">
  <link href="https://wg21.link/P1105R1" rel="canonical">
  <link href="https://isocpp.org/favicon.ico" rel="icon">
<style>/* 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>/* 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>/* style-syntax-highlighting */

.highlight:not(.idl) { background: hsl(24, 20%, 95%); }
code.highlight { padding: .1em; border-radius: .3em; }
pre.highlight, pre > code.highlight { display: block; padding: 1em; margin: .5em 0; overflow: auto; border-radius: 0; }
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 */
</style>
<style>/* style-selflinks */

.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%;
}
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: gray;
    color: white;
    font-style: normal;
    transition: opacity .2s, background-color .2s, color .2s;
}
dfn:hover > a.self-link {
    opacity: 1;
}
dfn > a.self-link:hover {
    color: black;
}

a.self-link::before            { content: "¶"; }
.heading > a.self-link::before { content: "§"; }
dfn > a.self-link::before      { content: "#"; }</style>
<style>/* style-autolinks */

.css.css, .property.property, .descriptor.descriptor {
    color: #005a9c;
    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;
}</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">P1105R1<br>Leaving no room for a lower-level language: A C++ Subset</h1>
   <h2 class="no-num no-toc no-ref heading settled" id="subtitle"><span class="content">Published Proposal, <time class="dt-updated" datetime="2018-10-06">2018-10-06</time></span></h2>
   <div data-fill-with="spec-metadata">
    <dl>
     <dt>This version:
     </dt><dd><a class="u-url" href="https://wg21.link/P1105R1">https://wg21.link/P1105R1</a>
     </dd><dt>Authors:
     </dt><dd>
      </dd><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> (<span class="p-org org">National Instruments</span>)
     </dd><dd>
      </dd><dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:ben@saksandassociates.com">Ben Saks</a> (<span class="p-org org">Saks &amp; Associates</span>)
     </dd><dt>Audience:
     </dt><dd>SG14, SG10, SG1, EWG, LEWG
     </dd><dt>Project:
     </dt><dd>ISO/IEC JTC1/SC22/WG21 14882: Programming Language — C++
     </dd><dt>Source:
     </dt><dd><a href="https://github.com/ben-craig/freestanding_proposal/blob/master/core/optional_exceptions.bs">github.com/ben-craig/freestanding_proposal/blob/master/core/optional_exceptions.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>
   <p>Making exceptions, dynamic RTTI, TLS, heap, floating point, program teardown, and blocking operations optional in freestanding mode.</p>
  </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="#revision_history"><span class="secno">1</span> <span class="content">Revision History</span></a>
     <ol class="toc">
      <li>
       <a href="#r0_r1"><span class="secno">1.1</span> <span class="content">r0 -&gt; r1</span></a>
       <ol class="toc">
        <li><a href="#sg14_july_2018"><span class="secno">1.1.1</span> <span class="content">SG14 telecon polls (July 11, 2018)</span></a>
        </li><li><a href="#sg14_online_july_2018"><span class="secno">1.1.2</span> <span class="content">SG14 post-telecon online poll (July 11-15, 2018)</span></a>
        </li><li><a href="#sg14_cppcon_sep_2018"><span class="secno">1.1.3</span> <span class="content">SG14 cppcon meeting (Sep 26, 2018)</span></a>
       </li></ol>
     </li></ol>
    </li><li><a href="#intro"><span class="secno">2</span> <span class="content">Introduction</span></a>
    </li><li><a href="#value"><span class="secno">3</span> <span class="content">Value of standardization</span></a>
    </li><li>
     <a href="#tony"><span class="secno">4</span> <span class="content">Before-and-after tables</span></a>
     <ol class="toc">
      <li><a href="#tony_no_change_impl_defined"><span class="secno">4.1</span> <span class="content">No-change, implementation defined</span></a>
      </li><li><a href="#tony_well_formed"><span class="secno">4.2</span> <span class="content">Well-formed</span></a>
      </li><li><a href="#tony_ill_formed"><span class="secno">4.3</span> <span class="content">Potentially ill-formed</span></a>
     </li></ol>
    </li><li>
     <a href="#features"><span class="secno">5</span> <span class="content">Features going optional</span></a>
     <ol class="toc">
      <li>
       <a href="#exceptions"><span class="secno">5.1</span> <span class="content">Exceptions</span></a>
       <ol class="toc">
        <li><a href="#exception_why"><span class="secno">5.1.1</span> <span class="content">Why make this optional?</span></a>
        </li><li><a href="#exception_same"><span class="secno">5.1.2</span> <span class="content">What isn’t changing?</span></a>
        </li><li><a href="#exception_what"><span class="secno">5.1.3</span> <span class="content">What am I changing (and why)?</span></a>
        </li><li><a href="#exception_alt"><span class="secno">5.1.4</span> <span class="content">Alternative designs</span></a>
        </li><li><a href="#exception_abi"><span class="secno">5.1.5</span> <span class="content">ABI impact</span></a>
       </li></ol>
      </li><li>
       <a href="#exception_header"><span class="secno">5.2</span> <span class="content">Parts of <code class="highlight"><c- o="">&lt;</c-><c- n="">exception</c-><c- o="">&gt;</c-></code> header</span></a>
       <ol class="toc">
        <li><a href="#exception_header_same"><span class="secno">5.2.1</span> <span class="content">What isn’t changing?</span></a>
        </li><li><a href="#exception_header_what"><span class="secno">5.2.2</span> <span class="content">What am I changing?</span></a>
        </li><li><a href="#exception_header_why"><span class="secno">5.2.3</span> <span class="content">Why?</span></a>
        </li><li><a href="#exception_header_alt"><span class="secno">5.2.4</span> <span class="content">Alternative designs</span></a>
       </li></ol>
      </li><li>
       <a href="#rtti"><span class="secno">5.3</span> <span class="content">Dynamic RTTI</span></a>
       <ol class="toc">
        <li><a href="#rtti_same"><span class="secno">5.3.1</span> <span class="content">What isn’t changing?</span></a>
        </li><li><a href="#rtti_what"><span class="secno">5.3.2</span> <span class="content">What am I changing?</span></a>
        </li><li><a href="#rtti_why"><span class="secno">5.3.3</span> <span class="content">Why?</span></a>
        </li><li><a href="#rtti_alt"><span class="secno">5.3.4</span> <span class="content">Alternative designs</span></a>
        </li><li><a href="#rtti_abi"><span class="secno">5.3.5</span> <span class="content">ABI impact</span></a>
       </li></ol>
      </li><li>
       <a href="#heap"><span class="secno">5.4</span> <span class="content">Default heap storage</span></a>
       <ol class="toc">
        <li><a href="#heap_same"><span class="secno">5.4.1</span> <span class="content">What isn’t changing?</span></a>
        </li><li><a href="#heap_what"><span class="secno">5.4.2</span> <span class="content">What am I changing?</span></a>
        </li><li><a href="#heap_why"><span class="secno">5.4.3</span> <span class="content">Why?</span></a>
        </li><li><a href="#heap_abi"><span class="secno">5.4.4</span> <span class="content">ABI impact</span></a>
       </li></ol>
      </li><li>
       <a href="#virtual_dtor"><span class="secno">5.5</span> <span class="content">Virtual destructors</span></a>
       <ol class="toc">
        <li><a href="#virtual_dtor_same"><span class="secno">5.5.1</span> <span class="content">What isn’t changing?</span></a>
        </li><li><a href="#virtual_dtor_what"><span class="secno">5.5.2</span> <span class="content">What am I changing?</span></a>
        </li><li><a href="#virtual_dtor_why"><span class="secno">5.5.3</span> <span class="content">Why?</span></a>
        </li><li><a href="#virtual_dtor_how"><span class="secno">5.5.4</span> <span class="content">How could this virtual destructor ODR-use change be implemented?</span></a>
        </li><li><a href="#virtual_dtor_abi"><span class="secno">5.5.5</span> <span class="content">ABI impact</span></a>
       </li></ol>
      </li><li>
       <a href="#tls"><span class="secno">5.6</span> <span class="content">Thread local storage</span></a>
       <ol class="toc">
        <li><a href="#tls_what"><span class="secno">5.6.1</span> <span class="content">What am I changing?</span></a>
        </li><li><a href="#tls_why"><span class="secno">5.6.2</span> <span class="content">Why?</span></a>
        </li><li><a href="#tls_abi"><span class="secno">5.6.3</span> <span class="content">ABI impact</span></a>
       </li></ol>
      </li><li>
       <a href="#float"><span class="secno">5.7</span> <span class="content">Floating point</span></a>
       <ol class="toc">
        <li><a href="#float_what"><span class="secno">5.7.1</span> <span class="content">What am I changing?</span></a>
        </li><li><a href="#float_why"><span class="secno">5.7.2</span> <span class="content">Why?</span></a>
        </li><li><a href="#float_abi"><span class="secno">5.7.3</span> <span class="content">ABI impact</span></a>
       </li></ol>
      </li><li>
       <a href="#startup_termination"><span class="secno">5.8</span> <span class="content">Program start-up and termination</span></a>
       <ol class="toc">
        <li><a href="#startup_termination_same"><span class="secno">5.8.1</span> <span class="content">What isn’t changing</span></a>
        </li><li><a href="#startup_termination_rationalization"><span class="secno">5.8.2</span> <span class="content">Rationalization for the status quo</span></a>
        </li><li><a href="#startup_termination_what"><span class="secno">5.8.3</span> <span class="content">What am I changing?</span></a>
        </li><li><a href="#startup_termination_why"><span class="secno">5.8.4</span> <span class="content">Why?</span></a>
        </li><li><a href="#startup_termination_alt"><span class="secno">5.8.5</span> <span class="content">Alternative designs</span></a>
        </li><li><a href="#startup_termination_abi"><span class="secno">5.8.6</span> <span class="content">ABI impact</span></a>
       </li></ol>
      </li><li>
       <a href="#blocking"><span class="secno">5.9</span> <span class="content">Language mandated blocking synchronization</span></a>
       <ol class="toc">
        <li><a href="#blocking_what"><span class="secno">5.9.1</span> <span class="content">What am I changing?</span></a>
        </li><li><a href="#blocking_why"><span class="secno">5.9.2</span> <span class="content">Why?</span></a>
        </li><li><a href="#blocking_abi"><span class="secno">5.9.3</span> <span class="content">ABI impact</span></a>
       </li></ol>
     </li></ol>
    </li><li>
     <a href="#other_work"><span class="secno">6</span> <span class="content">Related works in progress, and future work</span></a>
     <ol class="toc">
      <li><a href="#p0709"><span class="secno">6.1</span> <span class="content"><span>[P0709]</span> Zero-overhead deterministic exceptions</span></a>
      </li><li><a href="#p0784"><span class="secno">6.2</span> <span class="content"><span>[P0784]</span> Standard containers and <code class="highlight"><c- k="">constexpr</c-></code></span></a>
      </li><li><a href="#p1073"><span class="secno">6.3</span> <span class="content"><span>[P1073]</span> <code class="highlight"><c- k="">constexpr</c-><c- o="">!</c-></code> functions</span></a>
      </li><li><a href="#p1066"><span class="secno">6.4</span> <span class="content"><span>[P1066]</span> How to <code class="highlight"><c- k="">catch</c-></code> an <code class="highlight"><c- n="">exception_ptr</c-></code> without even <code class="highlight"><c- k="">try</c-></code>-ing</span></a>
      </li><li><a href="#explicit_startup_and_term"><span class="secno">6.5</span> <span class="content">Explicit control of program startup and termination</span></a>
     </li></ol>
    </li><li>
     <a href="#qoi"><span class="secno">7</span> <span class="content">Common QoI issues</span></a>
     <ol class="toc">
      <li><a href="#pure_virtual"><span class="secno">7.1</span> <span class="content">Pure virtual functions</span></a>
      </li><li><a href="#symbol_length"><span class="secno">7.2</span> <span class="content">Symbol name length</span></a>
     </li></ol>
    </li><li>
     <a href="#arguments"><span class="secno">8</span> <span class="content">Frequently raised arguments</span></a>
     <ol class="toc">
      <li><a href="#arguments_no_subsets"><span class="secno">8.1</span> <span class="content">C++ doesn’t standardize subsets</span></a>
      </li><li><a href="#arguments_user_fracture"><span class="secno">8.2</span> <span class="content">A subset will fracture the C++ user base</span></a>
      </li><li><a href="#arguments_multi_subset"><span class="secno">8.3</span> <span class="content">This doesn’t propose one subset, it defines many subsets</span></a>
      </li><li><a href="#arguments_vendor_burden"><span class="secno">8.4</span> <span class="content">A dialect will be burdensome to vendors</span></a>
      </li><li><a href="#arguments_different_subsets"><span class="secno">8.5</span> <span class="content">Everybody wants a different subset</span></a>
      </li><li><a href="#arguments_style_guides"><span class="secno">8.6</span> <span class="content">This doesn’t agree with common style guides, like MISRA</span></a>
      </li><li><a href="#arguments_committee_burden"><span class="secno">8.7</span> <span class="content">A subset will be burdensome for the committee</span></a>
     </li></ol>
    </li><li><a href="#ack"><span class="secno">9</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="revision_history"><span class="secno">1. </span><span class="content">Revision History</span><a class="self-link" href="#revision_history"></a></h2>
    Polls are all in the typical Strongly in Favor/Weakly in Favor/Neutral/Weakly Against/Strongly Against format. 
   <h3 class="heading settled" data-level="1.1" id="r0_r1"><span class="secno">1.1. </span><span class="content">r0 -&gt; r1</span><a class="self-link" href="#r0_r1"></a></h3>
    Freestanding-only <code class="highlight"><c- k="">noexcept</c-></code> semantics were dropped due to low value, low SG14 support, and ABI concerns. 
   <p><code class="highlight"><c- k="">throw</c-></code> statements now call <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">terminate</c-></code>, rather than cause UB. <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">terminate</c-></code> was the approach with the least opposition.</p>
   <p><code class="highlight"><c- k="">typeid</c-><c- p="">(</c-><c- n="">type</c-><c- p="">)</c-></code> now allowed.</p>
   <p>Added sections discussing ABI ramifications of changes.</p>
   <p>Changed thread-safe statics feature test macro.</p>
   <p>Clarifying <code class="highlight"><c- k="">if</c-> <c- k="">constexpr</c-></code> comments. <code class="highlight"><c- k="">catch</c-></code> blocks will still help determine auto return types.</p>
   <p>Added description of potential virtual destructor implementation.</p>
   <p>Added frequently raised arguments section.</p>
   <p>Added design alternative for program termination.</p>
   <h4 class="heading settled" data-level="1.1.1" id="sg14_july_2018"><span class="secno">1.1.1. </span><span class="content">SG14 telecon polls (July 11, 2018)</span><a class="self-link" href="#sg14_july_2018"></a></h4>
    <a href="https://groups.google.com/a/isocpp.org/forum/#!topic/sg14/8Ye0goaSosU">Minutes</a> 
   <p>Poll 1: get rid of freestanding<br> 0/1/2/9/11</p>
   <p>Poll 2: modify freestanding along the lines of the paper, encouragement for further work, agree with most of it<br> 5/13/4/0/0</p>
   <h4 class="heading settled" data-level="1.1.2" id="sg14_online_july_2018"><span class="secno">1.1.2. </span><span class="content">SG14 post-telecon online poll (July 11-15, 2018)</span><a class="self-link" href="#sg14_online_july_2018"></a></h4>
    <a href="https://groups.google.com/a/isocpp.org/forum/#!topic/sg14/cCMQb4jaEM8">Thread</a> 
   <p>Poll 3: noexcept should behave differently in environments without exceptions, along the lines of the paper<br> 0/4/3/5/0</p>
   <p>Poll 4: make throw UB when exceptions aren’t available<br> 0/3/6/3/1</p>
   <p>Poll 5: make throw ill-formed when exceptions aren’t available<br> 1/3/1/5/3</p>
   <p>Poll 6: make throw call std::terminate when exceptions aren’t available<br> 0/4/7/2/0</p>
   <h4 class="heading settled" data-level="1.1.3" id="sg14_cppcon_sep_2018"><span class="secno">1.1.3. </span><span class="content">SG14 cppcon meeting (Sep 26, 2018)</span><a class="self-link" href="#sg14_cppcon_sep_2018"></a></h4>
    <a href="http://wiki.edg.com/bin/view/Wg21sandiego2018/CPPCON2018SG14Meeting2018-09-26">Minutes</a><br> Poll: I want to know if we’re on board with a way to disable dynamic, type-based exceptions (this proposal is neutral with respect to static exceptions)<br> (no opposition in this room) 
   <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>
    Conforming C++ toolchains are ill-suited to target kernel and embedded domains.  In practice, kernel and embedded developers almost always use compiler switches that make the toolchain non-conforming.  This means that conforming C++ has left room for a lower-level language: non-conforming C++.  WG21 needs to decide between the lesser of several evils: formalizing a dialect, leaving room for a lower-level language, or massive breakage in real code.  If we do nothing, we will have left room for a lower-level language (C, non-conforming C++).  If we change hosted mode in a way to achieve the zero overhead, no lower-level language goal, we will end up needing to remove valuable features, breaking massive amounts of code.  This paper proposes formalizing a dialect. 
   <p>It is my intent that this be the least bad form of dialect, the proper subset.  All valid freestanding libraries should be valid hosted libraries with compatible semantics.</p>
   <p>This paper proposes making the following features optional: <a href="#exceptions">exceptions</a>, parts of the <a href="#exception_header"><code class="highlight"><span class="o"><c- o="">&lt;</c-></span><span class="n"><c- n="">exception</c-></span><span class="o"><c- o="">&gt;</c-></span></code> header</a>, <a href="#rtti"> dynamic RTTI</a>, <a href="#heap">default heap storage</a>, <a href="#tls">thread local storage</a>, <a href="#float">floating point</a>, the <a href="#startup_termination">atexit family of functions</a>, <a href="#blocking">locked atomics</a>, and <a href="#blocking">thread-safe static initialization</a>.</p>
   <p>In <a data-link-type="biblio" href="#biblio-p0829">[P0829]</a>, I propose adding library features to freestanding mode that should work everywhere.  This paper covers the removal and modification of features that don’t work everywhere.  There is already standards precedent in <a href="http://eel.is/c++draft/support.signal#3">support.signal</a> for avoiding portions of all the features that I am making optional.</p>
   <p>There are years, if not decades of field experience using C++ subsets similar to what I am proposing (<a data-link-type="biblio" href="#biblio-osr">[OSR]</a>, <a data-link-type="biblio" href="#biblio-apple_kernel">[APPLE_KERNEL]</a>).  The workarounds and compiler switches are mostly available today.  The main places where this paper innovates is in places where we can keep more features than current compiler based switches allow.</p>
   <p>In theory, this paper would result in large scale code breaks for existing freestanding users.  In practice, there are almost no existing freestanding users because the current definition is not serving the stated purpose of working <a href="http://eel.is/c++draft/intro.compliance#7">"without the benefit of an operating system"</a>.  Existing implementations already provide mechanisms for disabling many of the features that this paper proposes to make optional.  Updating these implementations to conform to this proposal would leave existing users largely unaffected, except that they would now be using a truly compliant C++ implementation.</p>
   <p>I believe that the embedded and kernel C++ community is better served by making features optional, rather than providing conforming, but low quality, highly unsatisfactory implementations.  Missing functionality sends a clear signal to library writers, where low quality implementations provide an easier to miss message.</p>
   <p>Note that freestanding implementations can (and should) make available all the features that are implementable on their target environment.  For example, there are many embedded systems where floating point operations are desirable, but heap allocations are not.  Each cluster of features will get its own feature test macro.  This has the effect of making all implementations compliant that are "between" the bare minimum freestanding and the full hosted implementation.</p>
   <h2 class="heading settled" data-level="3" id="value"><span class="secno">3. </span><span class="content">Value of standardization</span><a class="self-link" href="#value"></a></h2>
    What benefit does standardization bring to the kernel and embedded communities?  Kernel and embedded developers seem to be getting work done in non-conforming C++, so why should WG21 change course? 
   <p>First, I will answer those questions with another question: Why bring any proposal into the standard?  Presumably the authors of those proposals could get work done without the proposal.  Proposal authors are resourceful people, and can probably implement their papers in a fork of an existing compiler or standard library.  Yet they go through the hassle and expense of presenting papers to WG21 anyway.</p>
   <p>By making freestanding useful, I will be providing a target for toolchain and library authors.  Library authors that wish to make their libraries as portable as possible will have a standardized lowest common denominator to write against.  Purchasers will be better able to make requests of their vendors for freestanding compliant products.  Educators will be better able to teach about the requirements of kernel and embedded programming.  Tool vendors can better prioritize work on conforming compiler modes, and possibly reject new, ad-hoc non-conforming modes.  Users can get uniform behavior on what is currently an inconsistent set of vendor extensions.</p>
   <h2 class="heading settled" data-level="4" id="tony"><span class="secno">4. </span><span class="content">Before-and-after tables</span><a class="self-link" href="#tony"></a></h2>
   <h3 class="heading settled" data-level="4.1" id="tony_no_change_impl_defined"><span class="secno">4.1. </span><span class="content">No-change, implementation defined</span><a class="self-link" href="#tony_no_change_impl_defined"></a></h3>
   <p></p>
   <table>
    <tbody>
     <tr>
      <th>Code
      </th><th>Today’s conforming freestanding reality
      </th><th>Proposed conforming freestanding behavior
     </th></tr><tr>
      <td><code class="highlight"><pre class="highlight"><c- c1=""><c- c1="">//namespace scope</c-></c->
<c- k=""><c- k="">struct</c-></c-> <c- n=""><c- n="">Obj</c-></c-> <c- p=""><c- p="">{</c-></c->
    <c- n=""><c- n="">Obj</c-></c-><c- p=""><c- p="">();</c-></c->
    <c- o=""><c- o="">~</c-></c-><c- n=""><c- n="">Obj</c-></c-><c- p=""><c- p="">();</c-></c->
<c- p=""><c- p="">};</c-></c->
<c- n=""><c- n="">Obj</c-></c-> <c- n=""><c- n="">dynamic_default_init</c-></c-><c- p=""><c- p="">;</c-></c->
<c- b=""><c- b="">int</c-></c-> <c- n=""><c- n="">value_init</c-></c-> <c- o=""><c- o="">=</c-></c-> <c- mi=""><c- mi="">42</c-></c-><c- p=""><c- p="">;</c-></c->
<c- b=""><c- b="">int</c-></c-> <c- n=""><c- n="">zero_init</c-></c-><c- p=""><c- p="">;</c-></c-></pre></code>
      </td><td>
       Implementation defined, depending largely on behavior of the loader and whether the normal CRT entry is used / replicated. 
       <p>Whether <code class="highlight"><c- n="">Obj</c-><c- o="">::</c-><c- n="">Obj</c-><c- p="">()</c-></code> or <code class="highlight"><c- n="">Obj</c-><c- o="">::~</c-><c- n="">Obj</c-><c- p="">()</c-></code> are ever called is implementation defined.  It is implementation defined whether <code class="highlight"><c- n="">value_init</c-></code> contains <code class="highlight"><c- mi="">42</c-></code> or an indeterminate value.  It is implementation defined whether <code class="highlight"><c- n="">zero_init</c-></code> contains <code class="highlight"><c- mi="">0</c-></code> or an indeterminate value.</p>
      </td><td>No change
   </td></tr></tbody></table>
   <h3 class="heading settled" data-level="4.2" id="tony_well_formed"><span class="secno">4.2. </span><span class="content">Well-formed</span><a class="self-link" href="#tony_well_formed"></a></h3>
   <table>
    <tbody>
     <tr>
      <th>Standard says this should work
      </th><th>Today’s reality
      </th><th>Proposed conforming freestanding behavior
     </th></tr><tr>
      <td><code class="highlight"><c- k="">throw</c-> <c- mi="">0</c-><c- p="">;</c-></code>
      </td><td><b>Visual Studio 2017, /kernel</b> <br>error C2980: C++ exception handling is not supported with /kernel <br> <br><b>gcc 8.1, -fno-exceptions</b> <br>error: exception handling disabled, use -fexceptions to enable <br> <br><b>clang 6.0.0, -fno-exceptions</b> <br>error: cannot use "throw" with exceptions disabled <br> <br><b>gcc 8.1 and clang 6.0.0, -nostdlib</b> <br>undefined reference to "__cxa_allocate_exception" <br>undefined reference to "__cxa_throw" <br>undefined reference to "typeinfo for int" <br> <br><b>Bare metal gcc 4.8 with newlib</b> <br>undefined reference to "__exidx_end" <br>undefined reference to "__exidx_start" <br>undefined reference to "_exit" <br>undefined reference to "_sbrk" <br>undefined reference to "_kill" <br>undefined reference to "_getpid" <br>undefined reference to "_write" <br>undefined reference to "_close" <br>undefined reference to "_fstat" <br>undefined reference to "_isatty" <br>undefined reference to "_lseek" <br>undefined reference to "_read" 
      </td><td>
       <b>Proposed option:</b> <br><code class="highlight"><c- k="">throw</c-> <c- mi="">0</c-><c- p="">;</c-></code> and <code class="highlight"><c- k="">throw</c-><c- p="">;</c-></code> call <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">terminate</c-><c- p="">()</c-></code> if exceptions are not enabled. <code class="highlight"><c- k="">throw</c-><c- p="">;</c-></code> currently calls <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">terminate</c-><c- p="">()</c-></code> if executed outside of a <code class="highlight"><c- k="">catch</c-></code> block. <br> <br><b>Alternatives to be polled:</b> 
       <ul>
        <li>Ill-formed if exceptions are not enabled.
        </li><li>Undefined behavior if <code class="highlight"><c- k="">throw</c-> <c- mi="">0</c-><c- p="">;</c-></code> is executed and exceptions are not enabled.
       </li></ul>
     </td></tr><tr>
      <td><code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">bad_alloc</c-> <c- n="">e</c-><c- p="">;</c-></code>
      </td><td><b>Visual Studio 2017, /kernel</b> <br>error LNK2019: unresolved external symbol "void __cdecl operator delete(void *,unsigned __int64)" <br>error LNK2019: unresolved external symbol __std_exception_destroy <br> <br><b>gcc 8.1 and clang 6.0.0, -nostdlib</b> <br>undefined reference to "std::bad_alloc::~bad_alloc()" <br> <br><b>Bare metal gcc 4.8 with newlib</b> <br>undefined reference to "__exidx_end" <br>undefined reference to "__exidx_start" <br>undefined reference to "_exit" <br>undefined reference to "_sbrk" <br>undefined reference to "_kill" <br>undefined reference to "_getpid" <br>undefined reference to "_write" <br>undefined reference to "_close" <br>undefined reference to "_fstat" <br>undefined reference to "_isatty" <br>undefined reference to "_lseek" <br>undefined reference to "_read" 
      </td><td><b>Proposed option:</b> <br>Well-formed, but uncommon code.  Most likely to be seen in a discarded <code class="highlight"><c- k="">catch</c-></code> block. <br> <br><b>Alternative to be polled:</b> <br>Ill-formed if exceptions are not enabled. 
     </td></tr><tr>
      <td><code class="highlight"><pre class="highlight"><c- b=""><c- b="">void</c-></c-> <c- nf=""><c- nf="">caller</c-></c-><c- p=""><c- p="">()</c-></c-> <c- p=""><c- p="">{</c-></c->
    <c- k=""><c- k="">try</c-></c-> <c- p=""><c- p="">{</c-></c-><c- n=""><c- n="">foo</c-></c-><c- p=""><c- p="">();}</c-></c->
    <c- k=""><c- k="">catch</c-></c-><c- p=""><c- p="">(</c-></c-><c- k=""><c- k="">const</c-></c-> <c- n=""><c- n="">std</c-></c-><c- o=""><c- o="">::</c-></c-><c- n=""><c- n="">exception</c-></c-> <c- o=""><c- o="">&amp;</c-></c-><c- n=""><c- n="">e</c-></c-><c- p=""><c- p="">)</c-></c-> <c- p=""><c- p="">{</c-></c->
        <c- n=""><c- n="">log_exception</c-></c-><c- p=""><c- p="">(</c-></c-><c- n=""><c- n="">e</c-></c-><c- p=""><c- p="">.</c-></c-><c- n=""><c- n="">what</c-></c-><c- p=""><c- p="">());</c-></c->
        <c- k=""><c- k="">throw</c-></c-><c- p=""><c- p="">;</c-></c->
    <c- p=""><c- p="">}</c-></c->
<c- p=""><c- p="">}</c-></c-></pre></code>
      </td><td><b>Visual Studio 2017, /kernel</b> <br>error C2980: C++ exception handling is not supported with /kernel <br> <br><b>gcc 8.1, -fno-exceptions</b> <br>error: exception handling disabled, use -fexceptions to enable <br> <br><b>clang 6.0.0, -fno-exceptions</b> <br>error: cannot use "throw" with exceptions disabled <br>error: cannot use "try" with exceptions disabled <br> <br><b>gcc 8.1 and clang 6.0.0, -nostdlib</b> <br>undefined reference to "__cxa_begin_catch" <br>undefined reference to "__cxa_rethrow" <br>undefined reference to "__cxa_end_catch <br>undefined reference to "_Unwind_Resume" <br>undefined reference to "typeinfo for std::exception" <br>undefined reference to "__cxa_begin_catch" <br>undefined reference to "std::terminate()" <br>undefined reference to "__gxx_personality_v0" <br> <br><b>Bare metal gcc 4.8 with newlib</b> <br>undefined reference to "__exidx_end" <br>undefined reference to "__exidx_start" <br>undefined reference to "_exit" <br>undefined reference to "_sbrk" <br>etc... 
      </td><td><b>Proposed option:</b> <br>Well-formed. <br>When exceptions aren’t present, <code class="highlight"><c- k="">catch</c-></code> generates no code.  The <code class="highlight"><c- k="">try</c-></code> block is still executed, but does no exception bookkeeping, as is common in <code class="highlight"><c- n="">setjmp</c-></code> / <code class="highlight"><c- n="">longjmp</c-></code> EH implementations. <br>Names and syntax are still checked in catch blocks, similar to <code class="highlight"><c- k="">if</c-> <c- k="">constexpr</c-><c- p="">(</c->false<c- p="">)</c-></code>. <code class="highlight"><c- k="">auto</c-></code> deduced return types still use any <code class="highlight"><c- k="">return</c-></code> statements in the <code class="highlight"><c- k="">catch</c-></code> block, so as not to cause return types to vary based on presence of exceptions. 
     </td></tr><tr>
      <td><code class="highlight"><pre class="highlight"><c- k=""><c- k="">typeid</c-></c-><c- p=""><c- p="">(</c-></c-><c- b=""><c- b="">int</c-></c-><c- p=""><c- p="">);</c-></c-></pre></code>
      </td><td><b>Visual Studio 2017, /kernel</b> <br>Works! <br><b>Visual Studio 2017, /GR-</b> <br>Works! <br> <br><b>gcc 8.1 and clang 6.0.0, -fno-rtti</b> <br>error: cannot use typeid with -fno-rtti <br><b>gcc 8.1 and clang 6.0.0, -nostdlib</b> <br>undefined reference to "typeinfo for int" <br> <br><b>Bare metal gcc 4.8 with newlib</b> <br>undefined reference to "__exidx_end" <br>undefined reference to "__exidx_start" <br>undefined reference to "_exit" <br>undefined reference to "_sbrk" <br>etc... 
      </td><td><b>Proposed option:</b> <br>Well-formed, even if dynamic RTTI is not available. 
     </td></tr><tr>
      <td><code class="highlight"><pre class="highlight"><c- k=""><c- k="">struct</c-></c-> <c- n=""><c- n="">B</c-></c-> <c- p=""><c- p="">{</c-></c-><c- k=""><c- k="">virtual</c-></c-> <c- o=""><c- o="">~</c-></c-><c- n=""><c- n="">B</c-></c-><c- p=""><c- p="">()</c-></c-> <c- p=""><c- p="">{}</c-></c-> <c- p=""><c- p="">};</c-></c->
<c- b=""><c- b="">void</c-></c-> <c- nf=""><c- nf="">foo</c-></c-><c- p=""><c- p="">()</c-></c-> <c- p=""><c- p="">{</c-></c-><c- n=""><c- n="">B</c-></c-> <c- n=""><c- n="">b</c-></c-><c- p=""><c- p="">;}</c-></c-></pre></code>
      </td><td><b>Visual Studio 2017, /kernel</b> <br>error LNK2019: unresolved external symbol "void __cdecl operator delete(void *,unsigned)" <br> <br><b>gcc 8.1 and clang 6.0.0, -nostdlib</b> <br>undefined reference to "operator delete(void*, unsigned long)" <br>undefined reference to "vtable for __cxxabiv1::__class_type_info" 
      </td><td><b>Proposed option:</b> <br>Well-formed, even if the heap is not enabled. 
   </td></tr></tbody></table>
   <h3 class="heading settled" data-level="4.3" id="tony_ill_formed"><span class="secno">4.3. </span><span class="content">Potentially ill-formed</span><a class="self-link" href="#tony_ill_formed"></a></h3>
   <p></p>
   <table>
    <tbody>
     <tr>
      <th>Standard says this should work
      </th><th>Today’s reality
      </th><th>Proposed conforming freestanding behavior
     </th></tr><tr>
      <td><code class="highlight"><pre class="highlight"><c- k=""><c- k="">struct</c-></c-> <c- n=""><c- n="">B</c-></c-> <c- p=""><c- p="">{</c-></c-><c- k=""><c- k="">virtual</c-></c-> <c- b=""><c- b="">void</c-></c-> <c- n=""><c- n="">f</c-></c-><c- p=""><c- p="">()</c-></c-> <c- p=""><c- p="">{}};</c-></c->
<c- k=""><c- k="">struct</c-></c-> <c- nl=""><c- nl="">D</c-></c-> <c- p=""><c- p="">:</c-></c-> <c- n=""><c- n="">B</c-></c-> <c- p=""><c- p="">{</c-></c-><c- k=""><c- k="">virtual</c-></c-> <c- b=""><c- b="">void</c-></c-> <c- n=""><c- n="">f</c-></c-><c- p=""><c- p="">()</c-></c-> <c- p=""><c- p="">{}};</c-></c->
<c- n=""><c- n="">D</c-></c-> <c- o=""><c- o="">*</c-></c-><c- nf=""><c- nf="">func</c-></c-><c- p=""><c- p="">(</c-></c-><c- n=""><c- n="">B</c-></c-> <c- o=""><c- o="">*</c-></c-><c- n=""><c- n="">b</c-></c-><c- p=""><c- p="">)</c-></c-> <c- p=""><c- p="">{</c-></c->
    <c- k=""><c- k="">return</c-></c-> <c- k=""><c- k="">dynamic_cast</c-></c-><c- o=""><c- o="">&lt;</c-></c-><c- n=""><c- n="">D</c-></c-><c- o=""><c- o="">*&gt;</c-></c-><c- p=""><c- p="">(</c-></c-><c- n=""><c- n="">b</c-></c-><c- p=""><c- p="">);</c-></c->
<c- p=""><c- p="">}</c-></c-></pre></code>
      </td><td><b>Visual Studio 2017, /kernel</b> <br>error C2981: the dynamic form of "dynamic_cast" is not supported with /kernel <br> <br><b>gcc 8.1, -fno-rtti</b> <br>error: "dynamic_cast" not permitted with -fno-rtti <br> <br><b>clang 6.0.0, -fno-rtti</b> <br>error: cannot use dynamic_cast with -fno-rtti <br> <br><b>gcc 8.1 and clang 6.0.0, -nostdlib</b> <br>undefined reference to "__dynamic_cast" <br>undefined reference to "vtable for __cxxabiv1::__si_class_type_info" <br>undefined reference to "vtable for __cxxabiv1::__class_type_info" <br> <br><b>Bare metal gcc 4.8 with newlib</b> <br>undefined reference to "__exidx_end" <br>undefined reference to "__exidx_start" <br>undefined reference to "_exit" <br>undefined reference to "_sbrk" <br>etc... 
      </td><td><b>Proposed option:</b> <br>Ill-formed if dynamic RTTI is not enabled. 
     </td></tr><tr>
      <td><code class="highlight"><pre class="highlight"><c- cp=""><c- cp="">#include</c-></c-> &lt;typeinfo&gt;
<c- k=""><c- k="">struct</c-></c-> <c- n=""><c- n="">B</c-></c-> <c- p=""><c- p="">{</c-></c-><c- k=""><c- k="">virtual</c-></c-> <c- b=""><c- b="">void</c-></c-> <c- n=""><c- n="">f</c-></c-><c- p=""><c- p="">()</c-></c-> <c- p=""><c- p="">{}};</c-></c->
<c- k=""><c- k="">const</c-></c-> <c- b=""><c- b="">bool</c-></c-> <c- nf=""><c- nf="">func</c-></c-><c- p=""><c- p="">(</c-></c-><c- n=""><c- n="">B</c-></c-> <c- o=""><c- o="">&amp;</c-></c-><c- n=""><c- n="">b</c-></c-><c- p=""><c- p="">)</c-></c-> <c- p=""><c- p="">{</c-></c->
    <c- k=""><c- k="">return</c-></c-> <c- k=""><c- k="">typeid</c-></c-><c- p=""><c- p="">(</c-></c-><c- n=""><c- n="">b</c-></c-><c- p=""><c- p="">)</c-></c-> <c- o=""><c- o="">==</c-></c-> <c- k=""><c- k="">typeid</c-></c-><c- p=""><c- p="">(</c-></c-><c- b=""><c- b="">int</c-></c-><c- p=""><c- p="">);</c-></c->
<c- p=""><c- p="">}</c-></c-></pre></code>
      </td><td><b>Visual Studio 2017, /kernel</b> <br>error C2981: the dynamic form of "typeid" is not supported with /kernel <br> <br><b>gcc 8.1, -fno-rtti</b> <br>error: cannot use "typeid" with -fno-rtti <br> <br><b>clang 6.0.0, -fno-rtti</b> <br>error: cannot use typeid with -fno-rtti <br> <br><b>gcc 8.1 and clang 6.0.0, -nostdlib</b> <br>undefined reference to "typeinfo for int" <br>undefined reference to "strcmp" <br> <br><b>Bare metal gcc 4.8 with newlib</b> <br>undefined reference to "__exidx_end" <br>undefined reference to "__exidx_start" <br>undefined reference to "_exit" <br>undefined reference to "_sbrk" <br>etc... 
      </td><td><b>Proposed option:</b> <br>Ill-formed if dynamic RTTI is not enabled. 
     </td></tr><tr>
      <td><code class="highlight"><c- b="">void</c-> <c- nf="">f</c-><c- p="">(</c-><c- b="">int</c-> <c- o="">*</c-><c- n="">i</c-><c- p="">)</c-> <c- p="">{</c-><c- k="">delete</c-> <c- n="">i</c-><c- p="">;}</c-></code>
      </td><td><b>Visual Studio 2017, /kernel</b> <br>error LNK2019: unresolved external symbol "void __cdecl operator delete(void *)" <br> <br><b>gcc 8.1 and clang 6.0.0, -nostdlib</b> <br>undefined reference to "operator delete(void*, unsigned long)" <br> <br><b>Bare metal gcc 4.8 with newlib</b> <br>undefined reference to "_sbrk" 
      </td><td><b>Proposed option:</b> <br>Ill-formed if the heap is not enabled and <code class="highlight"><c- k="">operator</c-> <c- k="">delete</c-></code> has not been provided by the user. 
     </td></tr><tr>
      <td><code class="highlight"><pre class="highlight"><c- b=""><c- b="">int</c-></c-> <c- nf=""><c- nf="">foo</c-></c-><c- p=""><c- p="">()</c-></c-> <c- p=""><c- p="">{</c-></c->
    <c- k=""><c- k="">thread_local</c-></c-> <c- b=""><c- b="">int</c-></c-> <c- n=""><c- n="">x</c-></c-> <c- o=""><c- o="">=</c-></c-> <c- mi=""><c- mi="">0</c-></c-><c- p=""><c- p="">;</c-></c->
    <c- o=""><c- o="">++</c-></c-><c- n=""><c- n="">x</c-></c-><c- p=""><c- p="">;</c-></c->
    <c- k=""><c- k="">return</c-></c-> <c- n=""><c- n="">x</c-></c-><c- p=""><c- p="">;</c-></c->
<c- p=""><c- p="">}</c-></c-></pre></code>
      </td><td><b>Visual Studio 2017, /kernel</b> <br>error C2949: thread_local is not supported with /kernel <br> <br><b>gcc 8.1 and clang 6.0.0, -nostdlib</b> <br>successfully compiles, but corrupts memory associated with thread control block 
      </td><td><b>Proposed option:</b> <br>Ill-formed if thread-local storage is not enabled. 
     </td></tr><tr>
      <td><code class="highlight"><pre class="highlight"><c- b=""><c- b="">double</c-></c-> <c- nf=""><c- nf="">doubler</c-></c-><c- p=""><c- p="">(</c-></c-><c- b=""><c- b="">double</c-></c-> <c- n=""><c- n="">x</c-></c-><c- p=""><c- p="">)</c-></c-> <c- p=""><c- p="">{</c-></c->
    <c- k=""><c- k="">return</c-></c-> <c- n=""><c- n="">x</c-></c-> <c- o=""><c- o="">*</c-></c-> <c- mf=""><c- mf="">2.0</c-></c-><c- p=""><c- p="">;</c-></c->
<c- p=""><c- p="">}</c-></c-></pre></code>
      </td><td><b>Visual Studio 2017, /kernel</b> <br>successfully compiles, and corrupts user-mode floating point application state unless extra code is written to preserve the floating point state <br> <br><b>Bare metal gcc 4.8 with newlib</b> <br>successfully compiles, and even works, at the expense of 1052 bytes of floating point addition library code 
      </td><td><b>Proposed option:</b> <br>Ill-formed if floating point support is not enabled. 
     </td></tr><tr>
      <td><code class="highlight"><pre class="highlight"><c- b=""><c- b="">void</c-></c-> <c- nf=""><c- nf="">handler</c-></c-><c- p=""><c- p="">();</c-></c->
<c- b=""><c- b="">void</c-></c-> <c- nf=""><c- nf="">foo</c-></c-><c- p=""><c- p="">()</c-></c-> <c- p=""><c- p="">{</c-></c->
    <c- n=""><c- n="">atexit</c-></c-><c- p=""><c- p="">(</c-></c-><c- n=""><c- n="">handler</c-></c-><c- p=""><c- p="">);</c-></c->
<c- p=""><c- p="">}</c-></c-></pre></code>
      </td><td><b>Visual Studio 2017, /kernel</b> <br>error LNK2019: unresolved external symbol "int atexit(void)" <br> <br><b>gcc 8.1 and clang 6.0.0, -nostdlib</b> <br>undefined reference to "atexit" <br> <br><b>Bare metal gcc 4.8 with newlib</b> <br>undefined reference to "_sbrk" 
      </td><td><b>Proposed option:</b> <br>Ill-formed if dynamic initialization and tear-down support is not enabled. 
     </td></tr><tr>
      <td><code class="highlight"><pre class="highlight"><c- k=""><c- k="">struct</c-></c-> <c- n=""><c- n="">Obj</c-></c-> <c- p=""><c- p="">{</c-></c-><c- n=""><c- n="">Obj</c-></c-><c- p=""><c- p="">();};</c-></c->
<c- b=""><c- b="">void</c-></c-> <c- nf=""><c- nf="">foo</c-></c-><c- p=""><c- p="">()</c-></c-> <c- p=""><c- p="">{</c-></c->
    <c- k=""><c- k="">static</c-></c-> <c- n=""><c- n="">Obj</c-></c-> <c- n=""><c- n="">obj</c-></c-><c- p=""><c- p="">;</c-></c->
<c- p=""><c- p="">}</c-></c-></pre></code>
      </td><td><b>Visual Studio 2017, /kernel</b> <br>successfully compiles, but generates thread unsafe initialization for <code class="highlight"><c- n="">obj</c-></code>. <br> <br><b>gcc 8.1 and clang 6.0.0, -nostdlib</b> <br>undefined reference to "__cxa_guard_acquire" <br>undefined reference to "__cxa_guard_release" <br>undefined reference to "__cxa_guard_abort" <br>undefined reference to "_Unwind_Resume" <br>undefined reference to "__gxx_personality_v0" <br> <br><b>Bare metal gcc 4.8 with newlib</b> <br>undefined reference to "__exidx_end" <br>undefined reference to "__exidx_start" <br>undefined reference to "_exit" <br>undefined reference to "_sbrk" <br>etc... 
      </td><td><b>Proposed option:</b> <br>Ill-formed if blocking synchronization support is not enabled. 
     </td></tr><tr>
      <td><code class="highlight"><pre class="highlight"><c- k=""><c- k="">struct</c-></c-> <c- n=""><c- n="">BigData</c-></c-> <c- p=""><c- p="">{</c-></c->
    <c- b=""><c- b="">int</c-></c-> <c- n=""><c- n="">d</c-></c-><c- p=""><c- p="">[</c-></c-><c- mi=""><c- mi="">16</c-></c-><c- p=""><c- p="">];</c-></c->
<c- p=""><c- p="">};</c-></c->

<p><c- b=""><c- b="">void</c-></c-> <c- nf=""><c- nf="">foo</c-></c-><c- p=""><c- p="">(</c-></c->
    <c- n=""><c- n="">std</c-></c-><c- o=""><c- o="">::</c-></c-><c- n=""><c- n="">atomic</c-></c-><c- o=""><c- o="">&lt;</c-></c-><c- n=""><c- n="">BigData</c-></c-><c- o=""><c- o="">&gt;</c-></c-> <c- o=""><c- o="">&amp;</c-></c-><c- n=""><c- n="">lhs</c-></c-><c- p=""><c- p="">,</c-></c->
    <c- k=""><c- k="">const</c-></c-> <c- n=""><c- n="">BigData</c-></c-> <c- o=""><c- o="">&amp;</c-></c-><c- n=""><c- n="">rhs</c-></c-><c- p=""><c- p="">)</c-></c->
<c- p=""><c- p="">{</c-></c-><c- n=""><c- n="">lhs</c-></c-> <c- o=""><c- o="">=</c-></c-> <c- n=""><c- n="">rhs</c-></c-><c- p=""><c- p="">;}</c-></c-></p></pre></code>
      </td><td><b>Visual Studio 2017, /kernel</b> <br>successfully compiles, but generates spin locks that are dangerous when shared with interrupts. <br> <br><b>gcc 8.1 and clang 6.0.0, -nostdlib</b> <br>undefined reference to "__atomic_store" <br> <br><b>Bare metal gcc 4.8 with newlib</b> <br>undefined reference to "__atomic_store" 
      </td><td><b>Proposed option:</b> <br>Ill-formed if blocking synchronization support is not enabled. 
   </td></tr></tbody></table>
   <h2 class="heading settled" data-level="5" id="features"><span class="secno">5. </span><span class="content">Features going optional</span><a class="self-link" href="#features"></a></h2>
    The following applies only to freestanding mode.  Hosted mode will remain unchanged. 
   <p>The feature macros are somewhat backwards from how the macros are normally defined.  The macros are defined when the paper is adopted and the feature is missing.  We can’t define the macros in the past to say the features are present.  Testing for the "non-feature" macros is a safer and more backwards compatible way of determining whether the following features are present.</p>
   <h3 class="heading settled" data-level="5.1" id="exceptions"><span class="secno">5.1. </span><span class="content">Exceptions</span><a class="self-link" href="#exceptions"></a></h3>
    Feature test macro: <code class="highlight"><c- n="">__cpp_freestanding_no_exceptions</c-></code>.  Users can check <code class="highlight"><c- n="">__cpp_freestanding_no_exceptions</c-></code> when they want to determine what behavior <code class="highlight"><c- k="">throw</c-></code> will have.  The lack of the pre-existing <code class="highlight"><c- n="">__cpp_exceptions</c-></code> macro from <a data-link-type="biblio" href="#biblio-sd6">[SD6]</a> would not provide that information. 
   <p>This section applies to "dynamic" exceptions.  In other words, the exceptions we have had since C++98. <a data-link-type="biblio" href="#biblio-p0709">[P0709]</a> could add "static" exceptions.  I am keeping static exceptions in mind with this design, but I’m not providing any wording against that proposal.</p>
   <h4 class="heading settled" data-level="5.1.1" id="exception_why"><span class="secno">5.1.1. </span><span class="content">Why make this optional?</span><a class="self-link" href="#exception_why"></a></h4>
    Kernel and embedded environments can’t universally afford exceptions.  Throwing an exception requires a heap allocation on the Itanium ABI, and a large stack allocation on the Microsoft ABI, neither of which are suitable in kernel and embedded environments.  Throwing an exception requires TLS (<a href="#tls">§5.6 Thread local storage</a>) in order to propagate the number of uncaught exceptions.  Windows, Linux, Mac, and FreeBSD don’t allow drivers to store arbitrary TLS data, and they don’t have any special handling for C++ specific TLS requirements, like the number of uncaught exceptions. 
   <p>Even when exceptions aren’t thrown, there is a large space cost.  Table based exception costs grow roughly in proportion to the size and complexity of the program, and not in the number of <code class="highlight"><c- k="">throw</c-></code> sites, <code class="highlight"><c- k="">catch</c-></code> sites, or frames traversed in an exception <code class="highlight"><c- k="">throw</c-></code>.  Since table based exception costs grows with program size, rather than how much it is used, it is not zero overhead. <code class="highlight"><c- n="">setjmp</c-></code> / <code class="highlight"><c- n="">longjmp</c-></code> exception size costs are similar in these regards.</p>
   <p>See <a data-link-type="biblio" href="#biblio-p0709">[P0709]</a> for further discussion on the problems with exceptions.</p>
   <h4 class="heading settled" data-level="5.1.2" id="exception_same"><span class="secno">5.1.2. </span><span class="content">What isn’t changing?</span><a class="self-link" href="#exception_same"></a></h4>
    <code class="highlight"><c- k="">try</c-></code> and <code class="highlight"><c- k="">catch</c-></code> are both still allowed.  Compilers should treat <code class="highlight"><c- k="">catch</c-></code> blocks as discarded code (i.e. an <code class="highlight"><c- k="">if</c-> <c- k="">constexpr</c-><c- p="">(</c->false<c- p="">)</c-></code> block). <code class="highlight"><c- k="">try</c-></code> and <code class="highlight"><c- k="">catch</c-></code> blocks are allowed so that exception neutral code can be shared between freestanding and hosted implementations without requiring preprocessor hackery. 
   <p>A rethrow without an active exception currently calls <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">terminate</c-></code>.</p>
   <h4 class="heading settled" data-level="5.1.3" id="exception_what"><span class="secno">5.1.3. </span><span class="content">What am I changing (and why)?</span><a class="self-link" href="#exception_what"></a></h4>
    <code class="highlight"><c- k="">catch</c-></code> blocks are treated similarly to an <code class="highlight"><c- k="">if</c-> <c- k="">constexpr</c-><c- p="">(</c->false<c- p="">)</c-></code> block.  This is to allow many error handling cases to continue compiling without resorting to macros.  The contents of the <code class="highlight"><c- k="">catch</c-></code> block are discarded, but <code class="highlight"><c- k="">auto</c-></code> return type deduction will still respect the types in <code class="highlight"><c- k="">return</c-></code> statements within <code class="highlight"><c- k="">catch</c-></code> blocks.  The <code class="highlight"><c- k="">return</c-></code> type of the function should not typically depend on the presence or absence of exception support. 
   <p>Evaluating a <code class="highlight"><c- k="">throw</c-></code> expression in an environment without exception support calls <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">terminate</c-></code>.  We allow the programmer to compile with a <code class="highlight"><c- k="">throw</c-></code> to allow exception neutral code to be shared between freestanding and hosted implementations.  The <code class="highlight"><c- k="">throw</c-></code> should never be evaluated, since we shouldn’t be able to get into a <code class="highlight"><c- k="">catch</c-></code> block.</p>
   <p>We allow <code class="highlight"><c- k="">throw</c-></code> expressions so that programmers in environments with exceptions can catch the exception, and either translate the exception to another type of exception, rethrow the exception in a <a href="http://cppsecrets.blogspot.com/2013/12/using-lippincott-function-for.html">"Lippincott" function</a>, or handle the exception some other way.  In these cases, we have the expectation that the code will never run in the exceptionless environment.</p>
   <p>Implementations are encouraged to produce warnings on any <code class="highlight"><c- k="">throw</c-></code> expression with operands, as well as allow suppressions for informing the compiler when those <code class="highlight"><c- k="">throw</c-></code>s are actually there for exception translation purposes.</p>
   <h4 class="heading settled" data-level="5.1.4" id="exception_alt"><span class="secno">5.1.4. </span><span class="content">Alternative designs</span><a class="self-link" href="#exception_alt"></a></h4>
   <ol>
    <li data-md="">
     <p><code class="highlight"><c- k="">throw</c-></code> UB vs. ill-formed vs. <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">terminate</c-></code></p>
   </li></ol>
   <p>We could make some or all <code class="highlight"><c- k="">throw</c-></code> expressions ill-formed.  The benefit is that compilers could more reliably produce diagnostics.  The cost is that it would be more difficult to share exception neutral code between hosted and freestanding.  We have experience with this choice in the GCC and clang world with <code class="highlight"><c- o="">-</c-><c- n="">fno</c-><c- o="">-</c-><c- n="">exceptions</c-></code>.</p>
   <p>We could make <code class="highlight"><c- k="">throw</c-></code> statements UB.  UB likely optimizes better than <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">terminate</c-></code>.  Compilers would be able to remove any code that leads to the UB, reducing overall binary size.  We have experience with this choice in the Visual Studio world, when exceptions are disabled.</p>
   <p>We have library experience in libc++, libstdc++, and the Visual Studio STL with turning throws into varying forms of terminates.</p>
   <ol start="2">
    <li data-md="">
     <p><code class="highlight"><c- k="">try</c-></code> and <code class="highlight"><c- k="">catch</c-></code> allowed vs. ill-formed</p>
   </li></ol>
   <p>If we made <code class="highlight"><c- k="">try</c-></code> and <code class="highlight"><c- k="">catch</c-></code> ill-formed, we would severely impact the portability of libraries across the exception and non-exception worlds.  However, this is basically the status quo today, so we have experience with this pain.</p>
   <p>If we adopt everything else in this paper, while banning <code class="highlight"><c- k="">try</c-></code> and <code class="highlight"><c- k="">catch</c-></code>, we would be able to claim that freestanding C++ is signal safe C++.</p>
   <ol start="3">
    <li data-md="">
     <p>Only allow <code class="highlight"><c- k="">catch</c-><c- p="">(...)</c-></code> and <code class="highlight"><c- k="">throw</c-><c- p="">;</c-></code></p>
   </li></ol>
   <p>Logging exceptions and translating exceptions are less common use cases than simple <code class="highlight"><c- k="">catch</c-></code> and rethrow use cases.  Allowing <code class="highlight"><c- k="">catch</c-><c- p="">(</c-><c- n="">type</c-><c- p="">)</c-></code> takes us down the path of pulling in <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">exception</c-></code>, as well as making it difficult to diagnose inappropriate <code class="highlight"><c- k="">throw</c-> <c- n="">obj</c-><c- p="">;</c-></code> statements.  Pulling in <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">exception</c-></code> means that we must also remove the hard dependency of <code class="highlight"><c- k="">virtual</c-></code> destructor’s on <code class="highlight"><c- o="">::</c-><c- k="">operator</c-> <c- k="">delete</c-></code> (see <a href="#heap">§5.4 Default heap storage</a>).</p>
   <h4 class="heading settled" data-level="5.1.5" id="exception_abi"><span class="secno">5.1.5. </span><span class="content">ABI impact</span><a class="self-link" href="#exception_abi"></a></h4>
   <p>If an exception is thrown from exception-enabled code, across exception-disabled code, the results are undefined.  Structure sizes and mangled names of entities should be unaffected.</p>
   <h3 class="heading settled" data-level="5.2" id="exception_header"><span class="secno">5.2. </span><span class="content">Parts of <code class="highlight"><c- o="">&lt;</c-><c- n="">exception</c-><c- o="">&gt;</c-></code> header</span><a class="self-link" href="#exception_header"></a></h3>
    Feature test macro: <code class="highlight"><c- n="">__cpp_freestanding_no_exceptions</c-></code>. 
   <h4 class="heading settled" data-level="5.2.1" id="exception_header_same"><span class="secno">5.2.1. </span><span class="content">What isn’t changing?</span><a class="self-link" href="#exception_header_same"></a></h4>
    The <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">exception</c-></code> base class will still be available.  This class (and many of its children) need to exist so that hosted exception handling code can continue to log, translate, and handle errors, all while still compiling in freestanding mode. 
   <p><code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">terminate</c-></code> will still be available.  Various language features, most recently <a href="https://wg21.link/p0542">contracts</a>, rely on <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">terminate</c-></code>.  Freestanding will keep <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">terminate</c-></code> rather than respecify how all those features signal unrecoverable errors.</p>
   <h4 class="heading settled" data-level="5.2.2" id="exception_header_what"><span class="secno">5.2.2. </span><span class="content">What am I changing?</span><a class="self-link" href="#exception_header_what"></a></h4>
    Other than <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">exception</c-></code> and <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">terminate</c-></code>, nothing in the <code class="highlight"><c- o="">&lt;</c-><c- n="">exception</c-><c- o="">&gt;</c-></code> header will be present in environments without exception support.  This means the following facilities will no longer be required: 
   <ul>
    <li data-md="">
     <p><code class="highlight"><c- n="">terminate_handler</c-></code>, <code class="highlight"><c- n="">get_terminate_handler</c-></code> and <code class="highlight"><c- n="">set_terminate_handler</c-></code></p>
    </li><li data-md="">
     <p><code class="highlight"><c- n="">uncaught_exceptions</c-></code></p>
    </li><li data-md="">
     <p><code class="highlight"><c- n="">exception_ptr</c-></code>, <code class="highlight"><c- n="">current_exception</c-></code>, <code class="highlight"><c- n="">rethrow_exception</c-></code>, and <code class="highlight"><c- n="">make_exception_ptr</c-></code></p>
    </li><li data-md="">
     <p><code class="highlight"><c- n="">bad_exception</c-></code> and <code class="highlight"><c- n="">nested_exception</c-></code></p>
    </li><li data-md="">
     <p><code class="highlight"><c- n="">throw_with_nested</c-></code> and <code class="highlight"><c- n="">rethrow_if_nested</c-></code></p>
   </li></ul>
   <h4 class="heading settled" data-level="5.2.3" id="exception_header_why"><span class="secno">5.2.3. </span><span class="content">Why?</span><a class="self-link" href="#exception_header_why"></a></h4>
    The terminate handler functions require synchronizing a global variable.  Freestanding environments do not have a reliable way to do that (see <a href="#blocking">§5.9 Language mandated blocking synchronization</a>).  The default terminate handler is typically suitable. 
   <p><code class="highlight"><c- n="">uncaught_exceptions</c-></code> relies on thread-local storage (see <a href="#tls">§5.6 Thread local storage</a>).  Hard coding a return value of zero would work for existing implementations, but it would close off potential future designs (see <a href="#p0709">§6.1 [P0709] Zero-overhead deterministic exceptions</a>).</p>
   <p>The <code class="highlight"><c- n="">exception_ptr</c-></code> and <code class="highlight"><c- n="">throw_with_nested</c-></code> facilities require heap allocations and/or thread-local storage.</p>
   <h4 class="heading settled" data-level="5.2.4" id="exception_header_alt"><span class="secno">5.2.4. </span><span class="content">Alternative designs</span><a class="self-link" href="#exception_header_alt"></a></h4>
   <ol>
    <li data-md="">
     <p>Omit <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">exception</c-></code> and its children.</p>
   </li></ol>
   <p>This alternative would make it so that clients could only <code class="highlight"><c- k="">catch</c-><c- p="">(...)</c-></code> and <code class="highlight"><c- k="">catch</c-></code> their own client defined types.  This removes the ability of those clients to log or translate exceptions.  However, it would likely require less work on the implementation side, seeing as the current exception classes don’t work in kernel and embedded environments.</p>
   <ol start="2">
    <li data-md="">
     <p>Omit the entire <code class="highlight"><c- o="">&lt;</c-><c- n="">exception</c-><c- o="">&gt;</c-></code> header.</p>
   </li></ol>
   <p>In addition to the issues in the above alternative, we would also need to ensure that all the other library features and core language features didn’t call <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">terminate</c-></code> in freestanding mode.</p>
   <h3 class="heading settled" data-level="5.3" id="rtti"><span class="secno">5.3. </span><span class="content">Dynamic RTTI</span><a class="self-link" href="#rtti"></a></h3>
    Feature test macro: <code class="highlight"><c- n="">__cpp_freestanding_no_dynamic_rtti</c-></code>.  This macro is distinct from the <code class="highlight"><c- n="">__cpp_rtti</c-></code> macro already defined in <a data-link-type="biblio" href="#biblio-sd6">[SD6]</a>.  Users cannot currently (in 2018) reliably test for the presence of dynamic RTTI with <code class="highlight"><c- n="">__cpp_rtti</c-></code>, so dynamic RTTI should generally assumed to be present, unless <code class="highlight"><c- n="">__cpp_freestanding_no_dynamic_rtti</c-></code> is present. 
   <p>"Dynamic" RTTI is RTTI that requires some form of dynamic dispatch to resolve.  In particular, this covers <code class="highlight"><c- k="">dynamic_cast</c-></code> expressions and <code class="highlight"><c- k="">typeid</c-><c- p="">(</c-><c- n="">expr</c-><c- p="">)</c-></code> expressions that involve classes with virtual functions. <code class="highlight"><c- k="">typeid</c-><c- p="">(</c-><c- n="">type</c-><c- p="">)</c-></code> expressions can be resolved without indirection.</p>
   <h4 class="heading settled" data-level="5.3.1" id="rtti_same"><span class="secno">5.3.1. </span><span class="content">What isn’t changing?</span><a class="self-link" href="#rtti_same"></a></h4>
    <code class="highlight"><c- k="">typeid</c-><c- p="">(</c-><c- n="">type</c-><c- p="">)</c-></code> is required to be present and work.  Users only pay for the <code class="highlight"><c- n="">type_info</c-></code> objects they use with this syntax.  The <code class="highlight"><c- o="">&lt;</c-><c- n="">typeinfo</c-><c- o="">&gt;</c-></code> header is also required to be present. 
   <h4 class="heading settled" data-level="5.3.2" id="rtti_what"><span class="secno">5.3.2. </span><span class="content">What am I changing?</span><a class="self-link" href="#rtti_what"></a></h4>
    <code class="highlight"><c- k="">typeid</c-><c- p="">(</c-><c- n="">expr</c-><c- p="">)</c-></code> and <code class="highlight"><c- k="">dynamic_cast</c-></code> are ill-formed in environments without dynamic RTTI. 
   <h4 class="heading settled" data-level="5.3.3" id="rtti_why"><span class="secno">5.3.3. </span><span class="content">Why?</span><a class="self-link" href="#rtti_why"></a></h4>
    <code class="highlight"><c- k="">typeid</c-><c- p="">(</c-><c- n="">expr</c-><c- p="">)</c-></code> and <code class="highlight"><c- k="">dynamic_cast</c-></code> generally require vtables to point at a <code class="highlight"><c- n="">type_info</c-></code> object.  Those <code class="highlight"><c- n="">type_info</c-></code> objects consume space, and are difficult to optimize away.  If an instance of the class is ever created, the linker isn’t able to apply trivial dead data elimination techniques to get rid of the <code class="highlight"><c- n="">type_info</c-></code> object, as there exists a reference to the object from the vtable. <code class="highlight"><c- k="">typeid</c-><c- p="">(</c-><c- n="">type</c-><c- p="">)</c-></code> doesn’t require registering the <code class="highlight"><c- n="">type_info</c-></code> object in the vtable, so it is fine. 
   <p>The slot in the vtable itself is also a place where space is wasted.</p>
   <p>If <code class="highlight"><c- k="">typeid</c-><c- p="">(</c-><c- n="">expr</c-><c- p="">)</c-></code> and <code class="highlight"><c- k="">dynamic_cast</c-></code> can’t be called, implementations can safely remove the <code class="highlight"><c- n="">type_info</c-></code> objects, saving space.  Some ABIs will even permit reclaiming the vtable slot.</p>
   <p><code class="highlight"><c- k="">typeid</c-><c- p="">(</c-><c- n="">expr</c-><c- p="">)</c-></code> can throw if used on a null pointer.  Since we aren’t allowing <code class="highlight"><c- k="">typeid</c-><c- p="">(</c-><c- n="">expr</c-><c- p="">)</c-></code>, this isn’t a concern.</p>
   <h4 class="heading settled" data-level="5.3.4" id="rtti_alt"><span class="secno">5.3.4. </span><span class="content">Alternative designs</span><a class="self-link" href="#rtti_alt"></a></h4>
    We could also allow the subset of <code class="highlight"><c- k="">typeid</c-><c- p="">(</c-><c- n="">expr</c-><c- p="">)</c-></code> expressions that do not require dynamic dispatch.  If the static type of the expression resolves to a reference to a class with virtual functions, the program would be ill-formed.  I feel that this alternative would be more brittle, and more difficult to teach. 
   <h4 class="heading settled" data-level="5.3.5" id="rtti_abi"><span class="secno">5.3.5. </span><span class="content">ABI impact</span><a class="self-link" href="#rtti_abi"></a></h4>
    The current major implementations all provide ways to disable RTTI, so there is real world experience here. 
   <p>An object created in an RTTI-enabled implementation can be passed to a no-RTTI implementation, and the RTTI implementation can use it without any ill-effects.  A no-RTTI implementation can create an object, and pass it to an RTTI-enabled implementation, and everything will work fine, so long as <code class="highlight"><c- k="">typeid</c-></code> and <code class="highlight"><c- k="">dynamic_cast</c-></code> are not used on the object.</p>
   <p>A no-RTTI class can inherit from an RTTI class with no ill-effects.  An RTTI-enabled class cannot universally inherit from a no-RTTI class.</p>
   <p><code class="highlight"><c- k="">typeid</c-><c- p="">(</c-><c- n="">type</c-><c- p="">)</c-></code> across RTTI boundaries can cause trouble on some ABIs.  The Microsoft ABI eagerly emits <code class="highlight"><c- n="">type_info</c-></code> objects and falls back to string comparisons for <code class="highlight"><c- n="">type_info</c-></code> objects, so it gets by just fine.  The Itanium ABI doesn’t always emit <code class="highlight"><c- n="">type_info</c-></code> objects in each TU, so some cross RTTI-boundary cases will result in missing symbols.</p>
   <h3 class="heading settled" data-level="5.4" id="heap"><span class="secno">5.4. </span><span class="content">Default heap storage</span><a class="self-link" href="#heap"></a></h3>
    Feature test macro: <code class="highlight"><c- n="">__cpp_freestanding_no_default_heap</c-></code>. 
   <h4 class="heading settled" data-level="5.4.1" id="heap_same"><span class="secno">5.4.1. </span><span class="content">What isn’t changing?</span><a class="self-link" href="#heap_same"></a></h4>
    Non-allocating placement <code class="highlight"><c- o="">::</c-><c- k="">operator</c-> <c- k="">new</c-></code> and <code class="highlight"><c- o="">::</c-><c- k="">operator</c-> <c- k="">delete</c-></code> will still be present.  Users will still be allowed to implement the replaceable allocation and deallocation functions, as well as provide class specific implementations of <code class="highlight"><c- k="">operator</c-> <c- k="">new</c-></code> and <code class="highlight"><c- k="">operator</c-> <c- k="">delete</c-></code>. 
   <h4 class="heading settled" data-level="5.4.2" id="heap_what"><span class="secno">5.4.2. </span><span class="content">What am I changing?</span><a class="self-link" href="#heap_what"></a></h4>
    On systems without default heap storage, neither the replaceable allocation functions nor the replaceable deallocation functions are provided by default. 
   <h4 class="heading settled" data-level="5.4.3" id="heap_why"><span class="secno">5.4.3. </span><span class="content">Why?</span><a class="self-link" href="#heap_why"></a></h4>
    Many embedded systems do not have a heap.  Such a system could provide an implementation of <code class="highlight"><c- o="">::</c-><c- k="">operator</c-> <c- k="">new</c-></code> that immediately throws <code class="highlight"><c- n="">bad_alloc</c-></code>, but that would require pulling in all the exception handling machinery.  Returning <code class="highlight"><c- k="">nullptr</c-></code> would not be conforming, and would also take up a non-zero amount of space. 
   <p>Many kernel systems have multiple pools of memory, none of which is suitable as a default.  In the Microsoft Windows kernel, developers have the choice of paged pool, which is plentiful and dangerous; and non-paged pool, which is safe and scarce.  The National Instruments codebase has had experience using each of those options as a default, and both have proven problematic.  The Microsoft Visual Studio compiler switch <code class="highlight"><c- o="">/</c-><c- n="">kernel</c-></code> already implements the lack of default allocation functions. <a data-link-type="biblio" href="#biblio-kernel_switch">[kernel_switch]</a></p>
   <h4 class="heading settled" data-level="5.4.4" id="heap_abi"><span class="secno">5.4.4. </span><span class="content">ABI impact</span><a class="self-link" href="#heap_abi"></a></h4>
    No subtle affects.  If a program is expecting a heap to be present where it is not, then the program won’t work. 
   <h3 class="heading settled" data-level="5.5" id="virtual_dtor"><span class="secno">5.5. </span><span class="content">Virtual destructors</span><a class="self-link" href="#virtual_dtor"></a></h3>
    Feature test macro: <code class="highlight"><c- n="">__cpp_freestanding_no_default_heap</c-></code>. 
   <h4 class="heading settled" data-level="5.5.1" id="virtual_dtor_same"><span class="secno">5.5.1. </span><span class="content">What isn’t changing?</span><a class="self-link" href="#virtual_dtor_same"></a></h4>
    <code class="highlight"><c- k="">virtual</c-></code> destructors are still permitted and well formed. 
   <h4 class="heading settled" data-level="5.5.2" id="virtual_dtor_what"><span class="secno">5.5.2. </span><span class="content">What am I changing?</span><a class="self-link" href="#virtual_dtor_what"></a></h4>
    On systems without default heap storage, the presence of a <code class="highlight"><c- k="">virtual</c-></code> destructor shall not require <code class="highlight"><c- o="">::</c-><c- k="">operator</c-> <c- k="">delete</c-></code> to be provided unless an instance of the object is created with <code class="highlight"><c- k="">new</c-></code>.  Constructors and destructors will not ODR-use non-placement allocation and deallocation functions.  Instead <code class="highlight"><c- k="">new</c-></code> and <code class="highlight"><c- k="">delete</c-></code> expressions will ODR-use the non-placement allocation and dealloction functions.  (<a href="http://eel.is/c++draft/basic.def.odr#7">basic.def.odr</a>) 
   <h4 class="heading settled" data-level="5.5.3" id="virtual_dtor_why"><span class="secno">5.5.3. </span><span class="content">Why?</span><a class="self-link" href="#virtual_dtor_why"></a></h4>
    In current implementations of <code class="highlight"><c- k="">virtual</c-></code> destructors, the class’s vtable points at a stub function that calls the "real" destructor, then calls <code class="highlight"><c- o="">::</c-><c- k="">operator</c-> <c- k="">delete</c-></code>.  This places a burden on freestanding users of hosted code, even when the freestanding users aren’t using <code class="highlight"><c- k="">new</c-></code> and <code class="highlight"><c- k="">delete</c-></code>.  It seems reasonable to allow a freestanding class to have a <code class="highlight"><c- k="">virtual</c-></code> destructor, so long as the class is never <code class="highlight"><c- k="">new</c-></code>ed or <code class="highlight"><c- k="">delete</c-></code>ed.  Hosted uses of the class can <code class="highlight"><c- k="">new</c-></code> and <code class="highlight"><c- k="">delete</c-></code> all they want. 
   <h4 class="heading settled" data-level="5.5.4" id="virtual_dtor_how"><span class="secno">5.5.4. </span><span class="content">How could this virtual destructor ODR-use change be implemented?</span><a class="self-link" href="#virtual_dtor_how"></a></h4>
    First, this is only a problem that needs to be solved on systems without a default heap.  This means that typical user-mode desktop and server implementations would be unaffected. 
   <p>Existing linkers already have the ability to take multiple identical virtual table implementations and pick one for use in the final binary.  A potential implementation strategy is for compilers and linkers to support a new "weaker" linkage.  When the default heap is disabled, the compiler would emit a vtable with a <code class="highlight"><c- k="">nullptr</c-></code> or pure virtual function in the virtual destructor slot.  When <code class="highlight"><c- k="">new</c-></code> is called, a "stronger" linkage vtable would be emitted that has the deleting destructor in the virtual destructor slot.  The linker would then select a vtable with the strongest linkage available.  Today’s linkage would be considered "stronger".  Only partially filled vtables would have "weaker" linkage.</p>
   <h4 class="heading settled" data-level="5.5.5" id="virtual_dtor_abi"><span class="secno">5.5.5. </span><span class="content">ABI impact</span><a class="self-link" href="#virtual_dtor_abi"></a></h4>
    Mixing multiple object files into the same program should be fine, even if some of them have a default heap and some don’t.  All the regular / "strong" linkage vtables should be identical, and all the "weaker" linkage vtables should be identical.  If anyone in the program calls any form of <code class="highlight"><c- k="">new</c-></code>, the deleting destructor will be present and in the right slot.  If no-one calls <code class="highlight"><c- k="">new</c-></code> in the program, then no-one should be calling <code class="highlight"><c- k="">delete</c-></code>, and the empty vtable slot won’t be a problem. 
   <p>Shared libraries are trickier.  Vtables aren’t always emitted into every translation unit.  Take shared library "leaf" that has a default heap.  It depends upon shared library "root" that does not have a default heap.  If a class with a virtual destructor is defined in "root", along with its "key function", then a call to <code class="highlight"><c- k="">new</c-></code> on the class in "leaf" will generate an object with a partial vtable.  Calling <code class="highlight"><c- k="">delete</c-></code> on that object will cause UB (usually crashes).</p>
   <p>Lack of a default heap should generally be considered a trait of the platform.  Mixing this configuration shouldn’t be a common occurrence.</p>
   <h3 class="heading settled" data-level="5.6" id="tls"><span class="secno">5.6. </span><span class="content">Thread local storage</span><a class="self-link" href="#tls"></a></h3>
    Feature test macro: <code class="highlight"><c- n="">__cpp_freestanding_no_thread_local_storage</c-></code>. 
   <h4 class="heading settled" data-level="5.6.1" id="tls_what"><span class="secno">5.6.1. </span><span class="content">What am I changing?</span><a class="self-link" href="#tls_what"></a></h4>
    Programs using the <code class="highlight"><c- k="">thread_local</c-></code> storage class specifier are ill-formed if the environment does not provide thread local storage. 
   <h4 class="heading settled" data-level="5.6.2" id="tls_why"><span class="secno">5.6.2. </span><span class="content">Why?</span><a class="self-link" href="#tls_why"></a></h4>
    Thread local storage requires cooperation from the operating system. 
   <p>For embedded platforms, there may not be an operating system.  Implementing thread local storage on those platforms would be extra runtime overhead.</p>
   <p>For kernel platforms, and drivers in particular, the operating system may be owned by a third party.  The third party may not provide arbitrary thread local storage for plugins.  Neither Linux, Microsoft Windows, Apple OSX, FreeBSD, nor OpenRTOS support arbitrary thread local storage in the kernel.</p>
   <h4 class="heading settled" data-level="5.6.3" id="tls_abi"><span class="secno">5.6.3. </span><span class="content">ABI impact</span><a class="self-link" href="#tls_abi"></a></h4>
   <p>Disabling TLS should have no direct effect on the ABI.  In programs with mixed TLS settings, the no-TLS code should have no effect on the allocation or use of TLS in the TLS-enabled parts of the code.</p>
   <p>If a TLS-enabled function communicates information to callers or callees via TLS, then TLS-disabled code would not be capable of using that communication channel.</p>
   <h3 class="heading settled" data-level="5.7" id="float"><span class="secno">5.7. </span><span class="content">Floating point</span><a class="self-link" href="#float"></a></h3>
    Feature test macro: <code class="highlight"><c- n="">__cpp_freestanding_no_floating_point_support</c-></code>. 
   <h4 class="heading settled" data-level="5.7.1" id="float_what"><span class="secno">5.7.1. </span><span class="content">What am I changing?</span><a class="self-link" href="#float_what"></a></h4>
    The <code class="highlight"><c- b="">float</c-></code>, <code class="highlight"><c- b="">double</c-></code>, and <code class="highlight"><c- b="">long</c-> <c- b="">double</c-></code> types are ill-formed if the environment does not have floating point support. 
   <p><code class="highlight"><c- o="">&lt;</c-><c- n="">cfloat</c-><c- o="">&gt;</c-></code> is not required to be present in environments without floating point support. <code class="highlight"><c- n="">numeric_limits</c-><c- o="">&lt;</c-><c- n="">floating</c-> <c- n="">point</c-> <c- n="">type</c-><c- o="">&gt;</c-></code> is not required to be present in environments without floating point support.</p>
   <h4 class="heading settled" data-level="5.7.2" id="float_why"><span class="secno">5.7.2. </span><span class="content">Why?</span><a class="self-link" href="#float_why"></a></h4>
    Many embedded processors do not have floating point units.  The cost for the first usage of floating point is very high, as that pulls in floating point emulation libraries. 
   <p>In kernel environments, floating point operations are avoided.  The system call interface from user mode to kernel mode normally does a partial context switch, where it saves off the old values of registers, so that they can be restored when returning to user mode.  In order to make user / kernel transitions fast, operating systems usually don’t automatically save or restore the floating point state.  This means that carelessly using floating point in the kernel ends up corrupting the user mode program’s floating point state.</p>
   <h4 class="heading settled" data-level="5.7.3" id="float_abi"><span class="secno">5.7.3. </span><span class="content">ABI impact</span><a class="self-link" href="#float_abi"></a></h4>
    Floating point functions would not be usable (obviously).  When no floating point is used, the difference between hard-float and soft-float ABIs on ARM and MIPS should be none. 
   <p>Environments where floating point support is prohibited may need to use different implementations of some common functions.  For example, in many environments, <code class="highlight"><c- n="">memcpy</c-></code> will use vectorized instructions that touch floating point registers.  In an environment where floating point is prohibited (like many OS kernels), the implementation of <code class="highlight"><c- n="">memcpy</c-></code> will need to avoid using floating point registers.</p>
   <h3 class="heading settled" data-level="5.8" id="startup_termination"><span class="secno">5.8. </span><span class="content">Program start-up and termination</span><a class="self-link" href="#startup_termination"></a></h3>
    Feature test macros: 
   <ul>
    <li data-md="">
     <p><code class="highlight"><c- n="">__cpp_freestanding_no_static_initialization</c-></code>.</p>
    </li><li data-md="">
     <p><code class="highlight"><c- n="">__cpp_freestanding_no_dynamic_initialization</c-></code>.</p>
    </li><li data-md="">
     <p><code class="highlight"><c- n="">__cpp_freestanding_no_termination</c-></code>.</p>
   </li></ul>
   <h4 class="heading settled" data-level="5.8.1" id="startup_termination_same"><span class="secno">5.8.1. </span><span class="content">What isn’t changing</span><a class="self-link" href="#startup_termination_same"></a></h4>
    <a href="http://wg21.link/basic.start.main">basic.start.main</a> already makes start-up and termination implementation defined for freestanding implementations.  I interpret this as meaning that neither static initialization nor dynamic initialization is required to take place.  This also means that non-local object destruction is implementation defined. 
   <p><code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">abort</c-></code> and <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">terminate</c-></code> will remain in the library. <code class="highlight"><c- n="">_Exit</c-></code> will be in the library assuming <a data-link-type="biblio" href="#biblio-p0829">[P0829]</a> is accepted.</p>
   <h4 class="heading settled" data-level="5.8.2" id="startup_termination_rationalization"><span class="secno">5.8.2. </span><span class="content">Rationalization for the status quo</span><a class="self-link" href="#startup_termination_rationalization"></a></h4>
    Zero-overhead is a very sharp edge.  Initializing global, mutable data to zero requires the runtime code to know a range of bytes, and then the runtime code needs to memset those bytes to zero.  Applications that do not care about zero initialization could have better uses for those bytes and startup time. 
   <p>All code which runs before the user’s code could be considered unwanted overhead in some applications.  All code that runs after the user’s code could also be considered unwanted overhead.  Also, the "early" code that does initialization needs to be written in some language, and if we require zero initialization to happen before anything else, then that excludes C++ from being used to write early startup code.</p>
   <p>In practice, I expect zero initialization and static initialization to be the most used freestanding extension.</p>
   <p><code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">abort</c-></code> and <code class="highlight"><c- n="">_Exit</c-></code> do not call global destructors, global registration functions, or flush file I/O. <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">terminate</c-></code> does not call destructors or flush file I/O, but it does call a global registration function. <a href="#exception_header">§5.2 Parts of &lt;exception&gt; header</a> makes the getters and setters for the global registration function optional, so a freestanding <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">terminate</c-></code> doesn’t necessarily have a registration function either.  That leaves these as three functions that will end the program in an implementation defined way.</p>
   <h4 class="heading settled" data-level="5.8.3" id="startup_termination_what"><span class="secno">5.8.3. </span><span class="content">What am I changing?</span><a class="self-link" href="#startup_termination_what"></a></h4>
    The existence of <code class="highlight"><c- n="">atexit</c-></code>, <code class="highlight"><c- n="">at_quick_exit</c-></code>, <code class="highlight"><c- n="">exit</c-></code>, and <code class="highlight"><c- n="">quick_exit</c-></code> should be implementation defined (i.e. optional). 
   <h4 class="heading settled" data-level="5.8.4" id="startup_termination_why"><span class="secno">5.8.4. </span><span class="content">Why?</span><a class="self-link" href="#startup_termination_why"></a></h4>
    These functions require space overhead, and are difficult to optimize away.  Process termination code iterates over the contents of the <code class="highlight"><c- n="">atexit</c-></code> list, pinning the memory in place. 
   <h4 class="heading settled" data-level="5.8.5" id="startup_termination_alt"><span class="secno">5.8.5. </span><span class="content">Alternative designs</span><a class="self-link" href="#startup_termination_alt"></a></h4>
    We could also remove <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">abort</c-></code>, <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">terminate</c-></code>, and <code class="highlight"><c- n="">_Exit</c-></code>.  The C library implementers don’t necessarily know how to exit the program in whatever random environment a customer uses.  On some environments, jumping to address zero is a legitimate way to reset the processor.  In other environments, a system call is more appropriate. 
   <p>If we removed these functions, we would have no way to signal any kind of fatal error.  We would need to evaluate what that means for <code class="highlight"><c- k="">throw</c-></code> statements, contracts, and other language facilities.</p>
   <p>We could potentially use technology similar to replaceable <code class="highlight"><c- o="">::</c-><c- k="">operator</c-> <c- k="">new</c-></code> and <code class="highlight"><c- o="">::</c-><c- k="">operator</c-> <c- k="">delete</c-></code>.  Hosted implementations could provide a replaceable default terminate handler that could be replaced by a user-provided default terminate handler at build time.  Freestanding implementations would not provide a default implementation.  Usages of facilities that call <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">terminate</c-></code> would be ill formed if a default terminate handler were not provided.</p>
   <h4 class="heading settled" data-level="5.8.6" id="startup_termination_abi"><span class="secno">5.8.6. </span><span class="content">ABI impact</span><a class="self-link" href="#startup_termination_abi"></a></h4>
    None? 
   <p>Mixing TUs with different startup / termination settings may cause confusion ("Why do some globals get constructed but not others?"), but I do not foresee any ABI problems.</p>
   <h3 class="heading settled" data-level="5.9" id="blocking"><span class="secno">5.9. </span><span class="content">Language mandated blocking synchronization</span><a class="self-link" href="#blocking"></a></h3>
    Feature test macros: 
   <ul>
    <li data-md="">
     <p><code class="highlight"><c- n="">__cpp_freestanding_no_locked_atomics</c-></code>.</p>
    </li><li data-md="">
     <p><code class="highlight"><c- n="">__cpp_freestanding_no_non_global_dynamic_static_init</c-></code>.  This implies that __cpp_threadsafe_static_init is undefined.</p>
   </li></ul>
   <h4 class="heading settled" data-level="5.9.1" id="blocking_what"><span class="secno">5.9.1. </span><span class="content">What am I changing?</span><a class="self-link" href="#blocking_what"></a></h4>
    In environments without blocking synchronization support, dynamic initialization of function statics and non-lock-free atomics are ill-formed. 
   <p>In practice, this won’t require changes from toolchain vendors.  On unknown environments, the C++ runtime functions necessary to implement locked atomics and dynamic initialization of function statics generally aren’t provided.  This results in linker errors, satisfying the ill-formed requirement.  This change will make such a toolchain conforming.</p>
   <p>This change would break code migrating from C++98 to C++Next, as it will remove function static initialization that previously worked.  That same code would likely break in the C++98 to C++11 migration, as the function static initialization would require facilities not present in the environment.  Implementations would likely continue to provide compiler flags to aid the migration.</p>
   <h4 class="heading settled" data-level="5.9.2" id="blocking_why"><span class="secno">5.9.2. </span><span class="content">Why?</span><a class="self-link" href="#blocking_why"></a></h4>
    Blocking is hard and not universally portable. 
   <p>On a system without an OS, your main blocking choices are disabling interrupts and spin locks.  Spin locks are needed to synchronize among multiple hardware threads, and disabling interrupts is required when synchronizing a processor with itself.  Neither blocking technique is universally applicable, even when limited to the realm of OS-less systems.</p>
   <p>In the Windows kernel, there are multiple types of locks.  No one lock type is appropriate in all situations.</p>
   <p>The CRECT RTOS <a data-link-type="biblio" href="#biblio-crect">[CRECT]</a> doesn’t have independent locks like many other OSes do.  All locks are explicitly associated with a particular resource.  Jobs must list all resources they use so that scheduling priorities can be calculated at compile-time.  This effectively means that a CRECT application has N distinct lock types, used only by that application.  None of these locks are known to the maintainers of CRECT, and none of them are known to the C++ runtime.  Current compiler ABIs do not provide the C++ runtime with information about the type or address of the function static being initialized.</p>
   <p>Some OSes and applications are trying to meet hard real time guarantees.  Spin locks and disabled interrupts can add potentially unbounded jitter and latency to time critical operations, even when the operation isn’t performed on a time critical code path.</p>
   <p>Some OSes aren’t scheduled in a time-sliced manner.  Spin locks on these systems are a bad idea.  You could get in the middle of static initialization, get an interrupt that causes you to change threads, then get stuck on the initialization of the same static.  Forward progress will be halted until another interrupt happens at some indeterminate point in the future.</p>
   <p>All of these concerns are also concerns with regards to signals. <a href="https://wg21.link/support.signal">support.signal</a> already calls out that locked atomics result in UB when invoked from a signal.  Dynamic initialization of a static variable is also UB when invoked from a signal.  If we are willing to make special rules for signals, shouldn’t we be willing to make special rules for embedded and kernel... especially if the rules are largely the same?</p>
   <h4 class="heading settled" data-level="5.9.3" id="blocking_abi"><span class="secno">5.9.3. </span><span class="content">ABI impact</span><a class="self-link" href="#blocking_abi"></a></h4>
    None? 
   <p>If this paper had reverted thread-safe statics back to thread-unsafe statics, then there would be typical ODR problems.  Making the functions ill-formed avoids that problem though.</p>
   <h2 class="heading settled" data-level="6" id="other_work"><span class="secno">6. </span><span class="content">Related works in progress, and future work</span><a class="self-link" href="#other_work"></a></h2>
   <h3 class="heading settled" data-level="6.1" id="p0709"><span class="secno">6.1. </span><span class="content"><a data-link-type="biblio" href="#biblio-p0709">[P0709]</a> Zero-overhead deterministic exceptions</span><a class="self-link" href="#p0709"></a></h3>
    Static exceptions have the potential to be suitable for freestanding environments.  The usage of TLS for <code class="highlight"><c- n="">uncaught_exceptions</c-></code> is currently the main sticking point, but a potential option there is for a freestanding implementation to not track the number of in-flight exceptions. 
   <p>Efforts were made to not design out static exceptions.  If we were to ignore static exceptions and other potential implementations of exceptions, we could provide an implementation of <code class="highlight"><c- n="">uncaught_exceptions</c-></code> that always returned 0.  This would enable <code class="highlight"><c- n="">scope_success</c-></code> and <code class="highlight"><c- n="">scope_failure</c-></code> out of <a data-link-type="biblio" href="#biblio-p0052">[P0052]</a>.</p>
   <h3 class="heading settled" data-level="6.2" id="p0784"><span class="secno">6.2. </span><span class="content"><a data-link-type="biblio" href="#biblio-p0784">[P0784]</a> Standard containers and <code class="highlight"><c- k="">constexpr</c-></code></span><a class="self-link" href="#p0784"></a></h3>
    In theory, any program (including kernel and embedded program) should be able to use <code class="highlight"><c- k="">constexpr</c-></code> containers.  However, the proposal for <code class="highlight"><c- k="">constexpr</c-></code> containers requires <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">allocator</c-></code>.  Kernel and embedded systems may not want to provide <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">allocator</c-></code> at runtime.  There aren’t general purpose ways of providing constexpr classes at compile time without also providing them at runtime.  If this paper progresses, we may need to find a general purpose way of providing things at compile time, or we may need to find a special purpose way that will satisfy the <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">allocator</c-></code> use case.  Note that if we only solve the special case, we will likely need to solve other special cases, like <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">vector</c-></code>. 
   <p>One possible avenue for the <code class="highlight"><c- n="">std</c-><c- o="">::</c-><c- n="">allocator</c-></code> special case is for the implementation to provide declarations of all the methods, but provide no implementations.  The declarations may prove sufficient for the <code class="highlight"><c- k="">constexpr</c-></code> use case, while triggering linker errors in the runtime case.</p>
   <p>Or maybe, this could be tackled with conditionally <code class="highlight"><c- k="">constexpr</c-><c- o="">!</c-></code> functions...</p>
   <h3 class="heading settled" data-level="6.3" id="p1073"><span class="secno">6.3. </span><span class="content"><a data-link-type="biblio" href="#biblio-p1073">[P1073]</a> <code class="highlight"><c- k="">constexpr</c-><c- o="">!</c-></code> functions</span><a class="self-link" href="#p1073"></a></h3>
    P1073 provides a way to force a function to only be invokable at compile time.  Freestanding implementations could mark all <code class="highlight"><c- k="">constexpr</c-></code>, non-freestanding functions as <code class="highlight"><c- k="">constexpr</c-><c- o="">!</c-></code>. 
   <h3 class="heading settled" data-level="6.4" id="p1066"><span class="secno">6.4. </span><span class="content"><a data-link-type="biblio" href="#biblio-p1066">[P1066]</a> How to <code class="highlight"><c- k="">catch</c-></code> an <code class="highlight"><c- n="">exception_ptr</c-></code> without even <code class="highlight"><c- k="">try</c-></code>-ing</span><a class="self-link" href="#p1066"></a></h3>
    P1066 makes it possible to use <code class="highlight"><c- n="">exception_ptr</c-></code> without try, catch, or throw.  This may mean that it would be usable in an environment with no exceptions.  The feature would still require RTTI and the heap. 
   <h3 class="heading settled" data-level="6.5" id="explicit_startup_and_term"><span class="secno">6.5. </span><span class="content">Explicit control of program startup and termination</span><a class="self-link" href="#explicit_startup_and_term"></a></h3>
    At some point in the future, I would like to see a standard way to explicitly invoke constructors of globals and class statics, and a way to explicitly invoke the termination code.  This would give freestanding users the ability to control when these actions take place. 
   <h2 class="heading settled" data-level="7" id="qoi"><span class="secno">7. </span><span class="content">Common QoI issues</span><a class="self-link" href="#qoi"></a></h2>
   <h3 class="heading settled" data-level="7.1" id="pure_virtual"><span class="secno">7.1. </span><span class="content">Pure virtual functions</span><a class="self-link" href="#pure_virtual"></a></h3>
    In freestanding environments, compilers should prefer to fill in vtable slots for pure virtual functions with a null pointer, rather than with a pointer to a library support function (e.g. <code class="highlight"><c- n="">__cxa_pure_virtual</c-></code>).  The library support function takes up a small amount of space, all to support ease of debugging. 
   <h3 class="heading settled" data-level="7.2" id="symbol_length"><span class="secno">7.2. </span><span class="content">Symbol name length</span><a class="self-link" href="#symbol_length"></a></h3>
    Some systems (including certain configurations of the Linux kernel) keep around symbol names during runtime.  C++ symbol names usually encode return type information, parameter type information, enclosing namespaces and class names, and template arguments.  All this extra information makes for long, and often cryptic symbol names.  The long symbol names take up more space in the resulting binary, and the mangling scheme makes for more difficult debugging. 
   <p>The C++ standard does not govern name mangling, and this paper makes no concrete recommendations.  Implementations should strive to allow users to make useful tradeoffs between symbol name length, legibility, and ABI compatibility.</p>
   <h2 class="heading settled" data-level="8" id="arguments"><span class="secno">8. </span><span class="content">Frequently raised arguments</span><a class="self-link" href="#arguments"></a></h2>
   <h3 class="heading settled" data-level="8.1" id="arguments_no_subsets"><span class="secno">8.1. </span><span class="content">C++ doesn’t standardize subsets</span><a class="self-link" href="#arguments_no_subsets"></a></h3>
    C++ already has subsets and optional features.  C++98 through C++17 have a freestanding subset, that claims to be for systems without an OS.  This paper (and <a data-link-type="biblio" href="#biblio-p0829">[P0829]</a>) are trying to fulfill that goal. 
   <p><a href="http://eel.is/c++draft/support.signal#3">support.signal</a> identifies a subset of the language that is usable in signal handlers.</p>
   <p><code class="highlight"><c- k="">constexpr</c-></code> expressions are a subset of the language and library, with the additional burden of syntax.</p>
   <p>Most of <code class="highlight"><c- o="">&lt;</c-><c- n="">cstdint</c-><c- o="">&gt;</c-></code> is optional. <code class="highlight"><c- n="">random_device</c-></code> is optionally useful. <code class="highlight"><c- n="">native_handle</c-></code> functions and <code class="highlight"><c- n="">native_handle_type</c-></code> typedefs are optional.</p>
   <h3 class="heading settled" data-level="8.2" id="arguments_user_fracture"><span class="secno">8.2. </span><span class="content">A subset will fracture the C++ user base</span><a class="self-link" href="#arguments_user_fracture"></a></h3>
    The user base is already fractured, and has been for 20+ years.  This paper may allow more exception neutral code to be shared between code bases, even with the code bases have different exception settings.  I doubt we will ever be able to eliminate the user base fracture, but with the right feature additions and guidance, we can attempt to reduce the magnitude of the fracture. 
   <h3 class="heading settled" data-level="8.3" id="arguments_multi_subset"><span class="secno">8.3. </span><span class="content">This doesn’t propose one subset, it defines many subsets</span><a class="self-link" href="#arguments_multi_subset"></a></h3>
    No and yes. 
   <p>This paper proposes one lowest common denominator implementation.  Users can rely on that lowest common denominator to exist.  This is the one subset the paper defines.</p>
   <p>Vendors are allowed to provide hosted features that aren’t in the minimal freestanding subset.  This paper provides feature test macros and scoping of the feature test macros.  This paper doesn’t go into depth about the interaction of the various hosted features.  This paper hints at these many subsets.  None of the subsets that are between freestanding and hosted can be relied upon in a standards compliant portable manner.  If a user relies on a freestanding implementation that also provides dynamic RTTI (for example), then there is no guarantee that another vendor will provide a subset with the same set of features.</p>
   <h3 class="heading settled" data-level="8.4" id="arguments_vendor_burden"><span class="secno">8.4. </span><span class="content">A dialect will be burdensome to vendors</span><a class="self-link" href="#arguments_vendor_burden"></a></h3>
    This proposal increases the amount of available work, but does not increase the amount of required work. 
   <p>Vendors are only required to provide one conforming mode.  If a vendor doesn’t have a user base that is interested in freestanding, they won’t be forced to provide it in order to be conforming.  Conversely, if a vendor’s clients only care about freestanding, those vendors won’t be forced to provide a hosted implementation in order to be conforming.</p>
   <p>This proposal does expand the amount of potential work for vendors.  A vendor could choose to try and provide a full hosted toolchain, a minimal freestanding toolchain, and many different sets of features in between hosted and minimal freestanding.  Which subsets to implement is left to the discretion of the vendor.</p>
   <h3 class="heading settled" data-level="8.5" id="arguments_different_subsets"><span class="secno">8.5. </span><span class="content">Everybody wants a different subset</span><a class="self-link" href="#arguments_different_subsets"></a></h3>
    This is mostly true.  That’s why this paper aims for the lowest common denominator, and leaves extensions to the lowest common denominator up to vendors. 
   <h3 class="heading settled" data-level="8.6" id="arguments_style_guides"><span class="secno">8.6. </span><span class="content">This doesn’t agree with common style guides, like MISRA</span><a class="self-link" href="#arguments_style_guides"></a></h3>
    This paper concerns itself with what is technologically possible.  Style guides are too domain specific for something as general as a lowest common denominator subset. 
   <h3 class="heading settled" data-level="8.7" id="arguments_committee_burden"><span class="secno">8.7. </span><span class="content">A subset will be burdensome for the committee</span><a class="self-link" href="#arguments_committee_burden"></a></h3>
    Maintaining freestanding will require a small amount of ongoing committee time. 
   <p>On the language front, we should be striving for freestanding compatible in the first place.  Language features that are not freestanding compatible are likely not zero-cost abstractions.</p>
   <p>On the library front, we should watch for library features that naturally lend themselves to being freestanding, and encourage the authors to design their library as such.  Some library features don’t naturally lend themselves to being freestanding though, and that’s fine.  I/O facilities and dynamically sized containers are examples of facilities that can safely ignore freestanding mode.</p>
   <p>My expectation is that we spend more time worrying about ABI compatibility than we do about what is in freestanding and what isn’t.</p>
   <h2 class="heading settled" data-level="9" id="ack"><span class="secno">9. </span><span class="content">Acknowledgments</span><a class="self-link" href="#ack"></a></h2>
    Thank you to the many reviewers of this paper:
Brandon Streiff, Irwan Djajadi, Joshua Cannon, Brad Keryan, Alfred Bratterud, and Phil Hindman 
  </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-apple_kernel">[APPLE_KERNEL]
   </dt><dd>Apple Documentation. <a href="https://developer.apple.com/library/archive/documentation/DeviceDrivers/Conceptual/WritingDeviceDriver/CPluPlusRuntime/CPlusPlusRuntime.html">The libkern C++ Runtime</a>. URL: <a href="https://developer.apple.com/library/archive/documentation/DeviceDrivers/Conceptual/WritingDeviceDriver/CPluPlusRuntime/CPlusPlusRuntime.html">https://developer.apple.com/library/archive/documentation/DeviceDrivers/Conceptual/WritingDeviceDriver/CPluPlusRuntime/CPlusPlusRuntime.html</a>
   </dd><dt id="biblio-crect">[CRECT]
   </dt><dd>Emil Fresk; Odin Holmes; Carlos van Rooijen. <a href="https://github.com/korken89/crect">crect: A C++, compile-time, reactive RTOS</a>. URL: <a href="https://github.com/korken89/crect">https://github.com/korken89/crect</a>
   </dd><dt id="biblio-kernel_switch">[KERNEL_SWITCH]
   </dt><dd>Microsoft Documentation. <a href="https://docs.microsoft.com/en-us/cpp/build/reference/kernel-create-kernel-mode-binary">/kernel (Create Kernel Mode Binary)</a>. URL: <a href="https://docs.microsoft.com/en-us/cpp/build/reference/kernel-create-kernel-mode-binary">https://docs.microsoft.com/en-us/cpp/build/reference/kernel-create-kernel-mode-binary</a>
   </dd><dt id="biblio-osr">[OSR]
   </dt><dd>The NT Insider. <a href="http://www.osronline.com/article.cfm?article=57">Global Relief Effort - C++ Runtime Support for the NT DDK</a>. URL: <a href="http://www.osronline.com/article.cfm?article=57">http://www.osronline.com/article.cfm?article=57</a>
   </dd><dt id="biblio-p0052">[P0052]
   </dt><dd>Peter Sommerlad; Andrew L. Sandoval. <a href="http://wg21.link/P0052">Generic Scope Guard and RAII Wrapper for the Standard Library</a>. URL: <a href="http://wg21.link/P0052">http://wg21.link/P0052</a>
   </dd><dt id="biblio-p0709">[P0709]
   </dt><dd>Herb Sutter. <a href="http://wg21.link/P0709">Zero-overhead deterministic exceptions: Throw values</a>. URL: <a href="http://wg21.link/P0709">http://wg21.link/P0709</a>
   </dd><dt id="biblio-p0784">[P0784]
   </dt><dd>Louis Dionne; et al. <a href="http://wg21.link/P0784">Standard containers and constexpr</a>. URL: <a href="http://wg21.link/P0784">http://wg21.link/P0784</a>
   </dd><dt id="biblio-p0829">[P0829]
   </dt><dd>Ben Craig. <a href="http://wg21.link/P0829">Freestanding Proposal</a>. URL: <a href="http://wg21.link/P0829">http://wg21.link/P0829</a>
   </dd><dt id="biblio-p1066">[P1066]
   </dt><dd>Mathias Stearn. <a href="http://wg21.link/P1066">How to `catch` an `exception_ptr` without even `try`-ing</a>. URL: <a href="http://wg21.link/P1066">http://wg21.link/P1066</a>
   </dd><dt id="biblio-p1073">[P1073]
   </dt><dd>Richard Smith; Andrew Sutton; Daveed Vandevoorde. <a href="http://wg21.link/P1073">constexpr! functions</a>. URL: <a href="http://wg21.link/P1073">http://wg21.link/P1073</a>
   </dd><dt id="biblio-sd6">[SD6]
   </dt><dd>Clark Nelson. <a href="http://wg21.link/sd6">SD-6: SG10 Feature Test Recommendations</a>. URL: <a href="http://wg21.link/sd6">http://wg21.link/sd6</a>
  </dd></dl></body></html>