<!doctype html><html lang="en">
 <head>
  <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  <meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport">
  <title>P2186R1: Removing Garbage Collection Support</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)
 *
 ******************************************************************************/

/* color variables included separately for reliability */

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

	html {
		color: black;
		color: var(--text);
		background-color: white;
		background-color: var(--bg);
	}

	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;

		background: transparent top left fixed no-repeat;
		background-size: 25px auto;
	}


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

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

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

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

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

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

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

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

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

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

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

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

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

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

	@media print {
		#toc-nav {
			display: none;
		}
	}
	@media not print {
		#toc-nav {
			position: fixed;
			z-index: 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;
		}
		#toc-nav > a {
			display: block;
			white-space: nowrap;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	h1 + h2,
	#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) > :not(.head) + hr {
		font-size: 1.5em;
		text-align: center;
		margin: 1em auto;
		height: auto;
		color: black;
		color: var(--hr-text);
		border: transparent solid 0;
		background: transparent;
	}
	:not(.head) > hr::before {
		content: "\2727\2003\2003\2727\2003\2003\2727";
	}

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

	p {
		margin: 1em 0;
	}

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

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

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

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

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

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

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

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

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


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

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

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

	del {
		color: red;
		color: var(--del-text);
		background: transparent;
		background: var(--del-bg);
		text-decoration: line-through;
	}
	ins {
		color: #080;
		color: var(--ins-text);
		background: transparent;
		background: var(--ins-bg);
		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;
		hyphens: none;
		text-transform: none;
		text-align: left;
		text-align: start;
		font-variant: normal;
		orphans: 3;
		widows: 3;
		page-break-before: avoid;
	}
	pre code,
	code code {
		font-size: 100%;
	}

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

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

  /* Do something nice. */

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

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

	/* We hyperlink a lot, so make it less intrusive */
	a[href] {
		color: #034575;
		color: var(--a-normal-text);
		text-decoration: none;
		border-bottom: 1px solid #707070;
		border-bottom: 1px solid var(--a-normal-underline);
		/* Need a bit of extending for it to look okay */
		padding: 0 1px 0;
		margin: 0 -1px 0;
	}
	a:visited {
		color: #034575;
		color: var(--a-visited-text);
		border-bottom-color: #bbb;
		border-bottom-color: var(--a-visited-underline);
	}

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

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

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

	img {
		border-style: none;
	}

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

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

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

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

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

	.issue, .note, .example, .assertion, .advisement, blockquote {
		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;
	}


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


/*
Alternate table alignment rules

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

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

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

Possible extra rowspan handling

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

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

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


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

	.toc a {
		/* More spacing; use padding to make it part of the click target. */
		padding-top: 0.1rem;
		/* Larger, more consistently-sized click target */
		display: block;
		/* Reverse color scheme */
		color: black;
		color: var(--toclink-text);
		border-color: #3980b5;
		border-color: var(--toclink-underline);
	}
	.toc a:visited {
		color: black;
		color: var(--toclink-visited-text);
		border-color: #054572;
		border-color: var(--toclink-visited-underline);
	}
	.toc a: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; }
		}
		/* Loosen it on wide screens */
		@media screen and (min-width: 78em) {
			body:not(.toc-inline) :not(li) > .toc              { margin-left:  4rem; }
			body:not(.toc-inline) .toc .secno                  { margin-left: -4rem; }
			body:not(.toc-inline) .toc > li li li              { margin-left:  1rem; }
			body:not(.toc-inline) .toc > li li li .secno       { margin-left: -5rem; }
			body:not(.toc-inline) .toc > li li li li .secno    { margin-left: -6rem; }
			body:not(.toc-inline) .toc > li li li li li .secno { margin-left: -7rem; }
	}
	/* } */

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

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

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

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

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

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

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

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



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

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

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

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

	@media not print {
		.overlarge {
			overflow-x: auto;
			/* See Lea Verou's explanation background-attachment:
			 * http://lea.verou.me/2012/04/background-attachment-local/
			 *
			background: top left  / 4em 100% linear-gradient(to right,  #ffffff, rgba(255, 255, 255, 0)) local,
			            top right / 4em 100% linear-gradient(to left, #ffffff, rgba(255, 255, 255, 0)) local,
			            top left  / 1em 100% linear-gradient(to right,  #c3c3c5, rgba(195, 195, 197, 0)) scroll,
			            top right / 1em 100% linear-gradient(to left, #c3c3c5, rgba(195, 195, 197, 0)) scroll,
			            white;
			background-repeat: no-repeat;
			*/
		}
	}
</style>
<style 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;
    }

    del { background: #fcc; color: #000; text-decoration: line-through; }
    ins { background: #cfc; color: #000; }
    blockquote .highlight:not(.idl) { background: initial; margin: initial; padding: 0.5em }
    blockquote ul { background: inherit; }
    blockquote code.highlight:not(.idl) { padding: initial; }
    blockquote c-[a] { color: inherit; } /* Keyword.Declaration */
    blockquote c-[b] { color: inherit; } /* Keyword.Type */
    blockquote c-[c] { color: inherit; } /* Comment */
    blockquote c-[d] { color: inherit; } /* Comment.Multiline */
    blockquote c-[e] { color: inherit; } /* Name.Attribute */
    blockquote c-[f] { color: inherit; } /* Name.Tag */
    blockquote c-[g] { color: inherit; } /* Name.Variable */
    blockquote c-[k] { color: inherit; } /* Keyword */
    blockquote c-[l] { color: inherit; } /* Literal */
    blockquote c-[m] { color: inherit; } /* Literal.Number */
    blockquote c-[n] { color: inherit; } /* Name */
    blockquote c-[o] { color: inherit; } /* Operator */
    blockquote c-[p] { color: inherit; } /* Punctuation */
    blockquote c-[s] { color: inherit; } /* Literal.String */
    blockquote c-[t] { color: inherit; } /* Literal.String.Single */
    blockquote c-[u] { color: inherit; } /* Literal.String.Double */
    blockquote c-[cp] { color: inherit; } /* Comment.Preproc */
    blockquote c-[c1] { color: inherit; } /* Comment.Single */
    blockquote c-[cs] { color: inherit; } /* Comment.Special */
    blockquote c-[kc] { color: inherit; } /* Keyword.Constant */
    blockquote c-[kn] { color: inherit; } /* Keyword.Namespace */
    blockquote c-[kp] { color: inherit; } /* Keyword.Pseudo */
    blockquote c-[kr] { color: inherit; } /* Keyword.Reserved */
    blockquote c-[ld] { color: inherit; } /* Literal.Date */
    blockquote c-[nc] { color: inherit; } /* Name.Class */
    blockquote c-[no] { color: inherit; } /* Name.Constant */
    blockquote c-[nd] { color: inherit; } /* Name.Decorator */
    blockquote c-[ni] { color: inherit; } /* Name.Entity */
    blockquote c-[ne] { color: inherit; } /* Name.Exception */
    blockquote c-[nf] { color: inherit; } /* Name.Function */
    blockquote c-[nl] { color: inherit; } /* Name.Label */
    blockquote c-[nn] { color: inherit; } /* Name.Namespace */
    blockquote c-[py] { color: inherit; } /* Name.Property */
    blockquote c-[ow] { color: inherit; } /* Operator.Word */
    blockquote c-[mb] { color: inherit; } /* Literal.Number.Bin */
    blockquote c-[mf] { color: inherit; } /* Literal.Number.Float */
    blockquote c-[mh] { color: inherit; } /* Literal.Number.Hex */
    blockquote c-[mi] { color: inherit; } /* Literal.Number.Integer */
    blockquote c-[mo] { color: inherit; } /* Literal.Number.Oct */
    blockquote c-[sb] { color: inherit; } /* Literal.String.Backtick */
    blockquote c-[sc] { color: inherit; } /* Literal.String.Char */
    blockquote c-[sd] { color: inherit; } /* Literal.String.Doc */
    blockquote c-[se] { color: inherit; } /* Literal.String.Escape */
    blockquote c-[sh] { color: inherit; } /* Literal.String.Heredoc */
    blockquote c-[si] { color: inherit; } /* Literal.String.Interpol */
    blockquote c-[sx] { color: inherit; } /* Literal.String.Other */
    blockquote c-[sr] { color: inherit; } /* Literal.String.Regex */
    blockquote c-[ss] { color: inherit; } /* Literal.String.Symbol */
    blockquote c-[vc] { color: inherit; } /* Name.Variable.Class */
    blockquote c-[vg] { color: inherit; } /* Name.Variable.Global */
    blockquote c-[vi] { color: inherit; } /* Name.Variable.Instance */
    blockquote c-[il] { color: inherit; } /* Literal.Number.Integer.Long */
  </style>
  <meta content="Bikeshed version 89ebb6ab, updated Fri Oct 9 15:32:07 2020 -0700" name="generator">
  <link href="http://wg21.link/P2186R1" rel="canonical">
  <link href="https://isocpp.org/favicon.ico" rel="icon">
  <meta content="89ae248131deca348748e142cead62f323f1b8ba" name="document-revision">
<style>/* style-autolinks */

.css.css, .property.property, .descriptor.descriptor {
    color: var(--a-normal-text);
    font-size: inherit;
    font-family: inherit;
}
.css::before, .property::before, .descriptor::before {
    content: "‘";
}
.css::after, .property::after, .descriptor::after {
    content: "’";
}
.property, .descriptor {
    /* Don't wrap property and descriptor names */
    white-space: nowrap;
}
.type { /* CSS value <type> */
    font-style: italic;
}
pre .property::before, pre .property::after {
    content: "";
}
[data-link-type="property"]::before,
[data-link-type="propdesc"]::before,
[data-link-type="descriptor"]::before,
[data-link-type="value"]::before,
[data-link-type="function"]::before,
[data-link-type="at-rule"]::before,
[data-link-type="selector"]::before,
[data-link-type="maybe"]::before {
    content: "‘";
}
[data-link-type="property"]::after,
[data-link-type="propdesc"]::after,
[data-link-type="descriptor"]::after,
[data-link-type="value"]::after,
[data-link-type="function"]::after,
[data-link-type="at-rule"]::after,
[data-link-type="selector"]::after,
[data-link-type="maybe"]::after {
    content: "’";
}

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

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

[data-link-type=biblio] {
    white-space: pre;
}</style>
<style>/* style-colors */

/* Any --*-text not paired with a --*-bg is assumed to have a transparent bg */
html {
    color: black;
    color: var(--text);
    background-color: white;
    background-color: var(--bg);
}
:root {
    color-scheme: light dark;

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

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

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

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

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

    --heading-text: #005a9c;

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

    --algo-border: #def;

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

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

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

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

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

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

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

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

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

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

    --datacell-border: silver;

    --indexinfo-text: #707070;

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

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

    --editedrec-bg: darkorange;
}</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-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-selflinks */

:root {
    --selflink-text: white;
    --selflink-bg: gray;
    --selflink-hover-text: black;
}
.heading, .issue, .note, .example, li, dt {
    position: relative;
}
a.self-link {
    position: absolute;
    top: 0;
    left: calc(-1 * (3.5rem - 26px));
    width: calc(3.5rem - 26px);
    height: 2em;
    text-align: center;
    border: none;
    transition: opacity .2s;
    opacity: .5;
}
a.self-link:hover {
    opacity: 1;
}
.heading > a.self-link {
    font-size: 83%;
}
li > a.self-link {
    left: calc(-1 * (3.5rem - 26px) - 2em);
}
dfn > a.self-link {
    top: auto;
    left: auto;
    opacity: 0;
    width: 1.5em;
    height: 1.5em;
    background: var(--selflink-bg);
    color: var(--selflink-text);
    font-style: normal;
    transition: opacity .2s, background-color .2s, color .2s;
}
dfn:hover > a.self-link {
    opacity: 1;
}
dfn > a.self-link:hover {
    color: var(--selflink-hover-text);
}

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

code.highlight { padding: .1em; border-radius: .3em; }
pre.highlight, pre > code.highlight { display: block; padding: 1em; margin: .5em 0; overflow: auto; border-radius: 0; }

.highlight:not(.idl) { background: #fdf6e3; }
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-darkmode */

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

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

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

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

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

        --heading-text: #8af;

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

        --algo-border: #456;

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

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

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

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

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

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

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

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

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

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

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

        --datacell-border: silver;

        --indexinfo-text: #aaa;

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

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

        --editedrec-bg: darkorange;
    }
    /* In case a transparent-bg image doesn't expect to be on a dark bg,
       which is quite common in practice... */
    img { background: white; }
}
@media (prefers-color-scheme: dark) {
    :root {
        --selflink-text: black;
        --selflink-bg: silver;
        --selflink-hover-text: white;
    }
}

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

    c-[a] { color: #d33682 } /* Keyword.Declaration */
    c-[b] { color: #d33682 } /* Keyword.Type */
    c-[c] { color: #2aa198 } /* Comment */
    c-[d] { color: #2aa198 } /* Comment.Multiline */
    c-[e] { color: #268bd2 } /* Name.Attribute */
    c-[f] { color: #b58900 } /* Name.Tag */
    c-[g] { color: #cb4b16 } /* Name.Variable */
    c-[k] { color: #d33682 } /* Keyword */
    c-[l] { color: #657b83 } /* Literal */
    c-[m] { color: #657b83 } /* Literal.Number */
    c-[n] { color: #268bd2 } /* Name */
    c-[o] { color: #657b83 } /* Operator */
    c-[p] { color: #657b83 } /* Punctuation */
    c-[s] { color: #6c71c4 } /* Literal.String */
    c-[t] { color: #6c71c4 } /* Literal.String.Single */
    c-[u] { color: #6c71c4 } /* Literal.String.Double */
    c-[ch] { color: #2aa198 } /* Comment.Hashbang */
    c-[cp] { color: #2aa198 } /* Comment.Preproc */
    c-[cpf] { color: #2aa198 } /* Comment.PreprocFile */
    c-[c1] { color: #2aa198 } /* Comment.Single */
    c-[cs] { color: #2aa198 } /* Comment.Special */
    c-[kc] { color: #d33682 } /* Keyword.Constant */
    c-[kn] { color: #d33682 } /* Keyword.Namespace */
    c-[kp] { color: #d33682 } /* Keyword.Pseudo */
    c-[kr] { color: #d33682 } /* Keyword.Reserved */
    c-[ld] { color: #657b83 } /* Literal.Date */
    c-[nc] { color: #268bd2 } /* Name.Class */
    c-[no] { color: #268bd2 } /* Name.Constant */
    c-[nd] { color: #268bd2 } /* Name.Decorator */
    c-[ni] { color: #268bd2 } /* Name.Entity */
    c-[ne] { color: #268bd2 } /* Name.Exception */
    c-[nf] { color: #268bd2 } /* Name.Function */
    c-[nl] { color: #268bd2 } /* Name.Label */
    c-[nn] { color: #268bd2 } /* Name.Namespace */
    c-[py] { color: #268bd2 } /* Name.Property */
    c-[ow] { color: #657b83 } /* Operator.Word */
    c-[mb] { color: #657b83 } /* Literal.Number.Bin */
    c-[mf] { color: #657b83 } /* Literal.Number.Float */
    c-[mh] { color: #657b83 } /* Literal.Number.Hex */
    c-[mi] { color: #657b83 } /* Literal.Number.Integer */
    c-[mo] { color: #657b83 } /* Literal.Number.Oct */
    c-[sa] { color: #6c71c4 } /* Literal.String.Affix */
    c-[sb] { color: #6c71c4 } /* Literal.String.Backtick */
    c-[sc] { color: #6c71c4 } /* Literal.String.Char */
    c-[dl] { color: #6c71c4 } /* Literal.String.Delimiter */
    c-[sd] { color: #6c71c4 } /* Literal.String.Doc */
    c-[se] { color: #6c71c4 } /* Literal.String.Escape */
    c-[sh] { color: #6c71c4 } /* Literal.String.Heredoc */
    c-[si] { color: #6c71c4 } /* Literal.String.Interpol */
    c-[sx] { color: #6c71c4 } /* Literal.String.Other */
    c-[sr] { color: #6c71c4 } /* Literal.String.Regex */
    c-[ss] { color: #6c71c4 } /* Literal.String.Symbol */
    c-[fm] { color: #268bd2 } /* Name.Function.Magic */
    c-[vc] { color: #cb4b16 } /* Name.Variable.Class */
    c-[vg] { color: #cb4b16 } /* Name.Variable.Global */
    c-[vi] { color: #cb4b16 } /* Name.Variable.Instance */
    c-[vm] { color: #cb4b16 } /* Name.Variable.Magic */
    c-[il] { color: #657b83 } /* Literal.Number.Integer.Long */
}
</style>
 <body class="h-entry">
  <div class="head">
   <p data-fill-with="logo"></p>
   <h1 class="p-name no-ref" id="title">P2186R1<br>Removing Garbage Collection Support</h1>
   <h2 class="no-num no-toc no-ref heading settled" id="subtitle"><span class="content">Published Proposal, <time class="dt-updated" datetime="2020-12-14">2020-12-14</time></span></h2>
   <div data-fill-with="spec-metadata">
    <dl>
     <dt>This version:
     <dd><a class="u-url" href="http://wg21.link/P2186R1">http://wg21.link/P2186R1</a>
     <dt class="editor">Authors:
     <dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:cxx@jfbastien.com">JF Bastien</a> (<span class="p-org org">Toyota Research Institute—Advanced Development (Woven Planet)</span>)
     <dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:ameredith1@bloomberg.net">Alisdair Meredith</a> (<span class="p-org org">Bloomberg</span>)
     <dt>Audience:
     <dd>CWG, LWG
     <dt>Project:
     <dd>ISO/IEC JTC1/SC22/WG21 14882: Programming Language — C++
     <dt>Source:
     <dd><a href="https://github.com/jfbastien/papers/blob/master/source/P2186R1.bs">github.com/jfbastien/papers/blob/master/source/P2186R1.bs</a>
    </dl>
   </div>
   <div data-fill-with="warning"></div>
   <hr title="Separator for header">
  </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="#abstract"><span class="secno">1</span> <span class="content">Abstract</span></a>
    <li>
     <a href="#rev"><span class="secno">2</span> <span class="content">Revision History</span></a>
     <ol class="toc">
      <li><a href="#r0r1"><span class="secno">2.1</span> <span class="content">r0 ➡ r1</span></a>
     </ol>
    <li><a href="#history"><span class="secno">3</span> <span class="content">History</span></a>
    <li>
     <a href="#oops"><span class="secno">4</span> <span class="content">Issues with the Current Specification</span></a>
     <ol class="toc">
      <li><a href="#safe"><span class="secno">4.1</span> <span class="content">Safely Derived Pointers</span></a>
      <li><a href="#alloc"><span class="secno">4.2</span> <span class="content">Allocators</span></a>
      <li><a href="#new"><span class="secno">4.3</span> <span class="content">Replacement <code class="highlight"><c- k>operator</c-> <c- k>new</c-></code></span></a>
      <li><a href="#constexpr"><span class="secno">4.4</span> <span class="content"><code class="highlight"><c- k>constexpr</c-></code> Allocation</span></a>
      <li><a href="#corelib"><span class="secno">4.5</span> <span class="content">Core versus Library Wording</span></a>
      <li><a href="#CHAR_BIT"><span class="secno">4.6</span> <span class="content"><code class="highlight"><c- b>signed</c-> <c- b>char</c-></code> and <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>byte</c-></code></span></a>
      <li><a href="#prefer"><span class="secno">4.7</span> <span class="content">Preferred Pointer Safety</span></a>
      <li><a href="#c"><span class="secno">4.8</span> <span class="content">C Compatibility</span></a>
      <li><a href="#malloc"><span class="secno">4.9</span> <span class="content"><code class="highlight"><c- n>malloc</c-></code> and Related Functions</span></a>
     </ol>
    <li><a href="#rationale"><span class="secno">5</span> <span class="content">Rationale</span></a>
    <li><a href="#other"><span class="secno">6</span> <span class="content">Other Concerns</span></a>
    <li><a href="#proposal"><span class="secno">7</span> <span class="content">Proposal</span></a>
    <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>
     </ol>
   </ol>
  </nav>
  <main>
   <h2 class="heading settled" data-level="1" id="abstract"><span class="secno">1. </span><span class="content">Abstract</span><a class="self-link" href="#abstract"></a></h2>
   <p>We propose removing (<em>not</em> deprecating) C++'s Garbage Collection support. Specifically, these five library functions:</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- n>declare_reachable</c-></code></p>
    <li data-md>
     <p><code class="highlight"><c- n>undeclare_reachable</c-></code></p>
    <li data-md>
     <p><code class="highlight"><c- n>declare_no_pointers</c-></code></p>
    <li data-md>
     <p><code class="highlight"><c- n>undeclare_no_pointers</c-></code></p>
    <li data-md>
     <p><code class="highlight"><c- n>get_pointer_safety</c-></code></p>
   </ul>
   <p>As well as the <code class="highlight"><c- n>pointer_safety</c-></code> enum, the <code class="highlight"><c- n>__STDCPP_STRICT_POINTER_SAFETY__</c-></code> macro, and the Core Language wording.</p>
   <h2 class="heading settled" data-level="2" id="rev"><span class="secno">2. </span><span class="content">Revision History</span><a class="self-link" href="#rev"></a></h2>
   <h3 class="heading settled" data-level="2.1" id="r0r1"><span class="secno">2.1. </span><span class="content">r0 ➡ r1</span><a class="self-link" href="#r0r1"></a></h3>
   <p>EWG discussed this paper in a telecon on July 30th 2020, and LEWG discussed this
paper in a telecon on December 14th 2020. The following polls were taken:</p>
   <table class="def">
    <tbody>
     <tr>
      <th style="width: 70%;">
      <th><strong>SF</strong>
      <th><strong>F</strong>
      <th><strong>N</strong>
      <th><strong>A</strong>
      <th><strong>SA</strong>
     <tr>
      <th><small>EWG: Remove (not deprecate) garbage collection support in C++23.</small>
      <th>3
      <th>9
      <th>4
      <th>0
      <th>1
     <tr>
      <th><small>LEWG: Remove (not deprecate) pointer safety in C++23, after moving names to zombie names.</small>
      <th>10
      <th>4
      <th>3
      <th>0
      <th>0
   </table>
   <p>The library names were added to the zombie names section.</p>
   <h2 class="heading settled" data-level="3" id="history"><span class="secno">3. </span><span class="content">History</span><a class="self-link" href="#history"></a></h2>
   <p>Minimal support for Garbage Collection was added to C++0x in 2008 by <a data-link-type="biblio" href="#biblio-n2670">[N2670]</a>. The main addition was the concept of "strict pointer safety", as well as library support for this pointer safety. Most of the rationale leading to the wording in this paper is captured in the two preceding proposals that merged to form this minimal paper, <a data-link-type="biblio" href="#biblio-n2310">[N2310]</a> and <a data-link-type="biblio" href="#biblio-n2585">[N2585]</a>.</p>
   <p>There have been successful garbage collectors for C++, for example the <a href="https://www.hboehm.info/gc/">Boehm GC</a> as well as Garbage Collectors in language virtual machines where the VM is implemented in C++, to support a garbage-collected language. This allows the implementation language to reference objects in the garbage collected language, and lets them interface very closely. You’re likely reading this paper in such a virtual machine, implemented in C++, with support for garbage collection: JavaScript VMs do this. Similarly, you’ve probably played games which mix C++ and C# using the Unity game engine, which <a href="https://docs.unity3d.com/Manual/UnderstandingAutomaticMemoryManagement.html">relies on the Boehm GC</a>.</p>
   <p>Example of virtual machines written in C++ with support for garbage collection include:</p>
   <ul>
    <li data-md>
     <p>WebKit’s JavaScriptCore use a garbage collector called <a href="https://webkit.org/blog/7122/introducing-riptide-webkits-retreating-wavefront-concurrent-garbage-collector/">Riptide</a>.</p>
    <li data-md>
     <p>Chromium’s <a href="https://chromium.googlesource.com/chromium/src/+/master/third_party/blink/renderer/platform/heap/BlinkGCAPIReference.md">Blink GC called Oilpan</a>. The V8 blog has <a href="https://v8.dev/blog/high-performance-cpp-gc">a good overview of Oilpan</a>. The V8 JavaScript engine used by Chromium also has its own garbage collector called <a href="https://v8.dev/blog/trash-talk">Orinoco</a>.</p>
    <li data-md>
     <p>Firefox’s SpiderMonkey JavaScript engine also <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Internals/Garbage_collection">has a garbage collector</a>.</p>
    <li data-md>
     <p>Lua and LuaJIT <a href="http://wiki.luajit.org/New-Garbage-Collector">use garbage collection</a>.</p>
   </ul>
   <p>As you can see from their documentation, each garbage collector has its own set of design criteria which influence how the language itself is implemented, and how the C++ runtime is written to obey the chosen design. These languages use similar ideas, but the design is different in each case, and the constraints on C++ code are different.</p>
   <h2 class="heading settled" data-level="4" id="oops"><span class="secno">4. </span><span class="content">Issues with the Current Specification</span><a class="self-link" href="#oops"></a></h2>
   <p>We illustrate a few problems with the current specification as it stands, in some cases where the current specification is overly restrictive, and in others where it falls short.</p>
   <h3 class="heading settled" data-level="4.1" id="safe"><span class="secno">4.1. </span><span class="content">Safely Derived Pointers</span><a class="self-link" href="#safe"></a></h3>
   <p>The complete list of ways to create a safely-derived pointer is itemized in <strong>[basic.stc.dynamic.safety]</strong> ❡2. The list is mostly manipulation of existing safely-derived pointers, where the only way to create the initial safely-derived pointer is through a call to one of two specified overloads of global <code class="highlight"><c- o>::</c-><c- k>operator</c-> <c- k>new</c-></code>. It does not have an escape hatch for implementation-defined behavior adding additional ways to create a safely derived pointer. In particular, calls to global array-<code class="highlight"><c- k>new</c-></code>, or no-throw <code class="highlight"><c- k>new</c-></code>, do not produce safely-derived pointers unless defined to call one of the two specified overloads.</p>
   <p>However, the most troubling example is using in-place new to create object in local arrays, a common strategy to avoid unnecessary heap usage:</p>
<pre class="highlight"><code class="highlight"><c- cp><c- cp>#include</c-></c-> &lt;new>

<c- b><c- b>int</c-></c-> <c- nf><c- nf>main</c-></c-><c- p><c- p>()</c-></c-> <c- p><c- p>{</c-></c->
   <c- b><c- b>char</c-></c-> <c- n><c- n>buffer</c-></c-><c- p><c- p>[</c-></c-><c- k><c- k>sizeof</c-></c-><c- p><c- p>(</c-></c-><c- b><c- b>int</c-></c-><c- p><c- p>)]</c-></c-> <c- k><c- k>alignas</c-></c-><c- p><c- p>(</c-></c-><c- b><c- b>int</c-></c-><c- p><c- p>);</c-></c-> <c- c1><c- c1>// automatic storage duration</c-></c->
   <c- b><c- b>void</c-></c-> <c- o><c- o>*</c-></c-><c- n><c- n>ptr</c-></c-> <c- o><c- o>=</c-></c-> <c- n><c- n>buffer</c-></c-><c- p><c- p>;</c-></c->
   <c- b><c- b>int</c-></c-> <c- o><c- o>*</c-></c-><c- n><c- n>pint</c-></c-> <c- o><c- o>=</c-></c-> <c- k><c- k>new</c-></c-><c- p><c- p>(</c-></c-><c- n><c- n>ptr</c-></c-><c- p><c- p>)</c-></c-> <c- b><c- b>int</c-></c-><c- p><c- p>(</c-></c-><c- mi><c- mi>0</c-></c-><c- p><c- p>);</c-></c->           <c- c1><c- c1>// dynamic storage duration</c-></c->
   <c- k><c- k>return</c-></c-> <c- o><c- o>*</c-></c-><c- n><c- n>pint</c-></c-><c- p><c- p>;</c-></c->                          <c- c1><c- c1>// UB with strict pointer safety</c-></c->
<c- p><c- p>}</c-></c->
</code></pre>
   <p>Instinctively, we might reach for <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>declare_reachable</c-></code> to solve such matters ourselves, at the expense of complicating portable code for the befit of well-defined behavior on strict pointer safety systems. Alas! This does not work, as the precondition on <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>declare_reachable</c-></code> is that the supplied pointer be safely-derived—the very problem we are trying to solve by using this function! Even if that precondition were relaxed, there would be a problem calling <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>undeclare_reachable</c-></code> before the function returns.</p>
   <h3 class="heading settled" data-level="4.2" id="alloc"><span class="secno">4.2. </span><span class="content">Allocators</span><a class="self-link" href="#alloc"></a></h3>
   <p>Safely derived pointers to dynamic memory cannot be provided other than by calls to <code class="highlight"><c- o>::</c-><c- k>operator</c-> <c- k>new</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- b>size_t</c-><c- p>)</c-></code> or <code class="highlight"><c- o>::</c-><c- k>operator</c-> <c- k>new</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- b>size_t</c-><c- p>,</c-> <c- n>std</c-><c- o>::</c-><c- n>align_val_t</c-><c- p>)</c-></code>, see <strong>[basic.stc.dynamic.safety]</strong> ❡1. This means we have no support for OS memory allocation functions, such as <code class="highlight"><c- n>VirtualAlloc</c-></code> or <code class="highlight"><c- n>HeapAlloc</c-></code> on Windows, or use of memory mapped files for interprocess communication.</p>
   <p>Custom memory allocation, as might be supplied by a type that meets the allocator requirements, or implements the <code class="highlight"><c- n>prm</c-><c- o>::</c-><c- n>memory_resource</c-></code> interface, typically rely on such allocation subsystems, and would need some as yet unspecified scheme to indicate that they hold valid memory that could hold pointers to live objects. Note that simply calling <code class="highlight"><c- n>declare_reachable</c-></code> on every attempt to construct an object through such an allocator is not sufficient, as that function has a precondition that the pointer argument is safely-derived—exactly the problem we are trying to solve.</p>
   <h3 class="heading settled" data-level="4.3" id="new"><span class="secno">4.3. </span><span class="content">Replacement <code class="highlight"><c- k>operator</c-> <c- k>new</c-></code></span><a class="self-link" href="#new"></a></h3>
   <p>The only two library functions guaranteed to return a safely-derived pointer are <em>replaceable</em>, but there is no mention in the library specification of what it means to replace these functions on an implementation with strict pointer safety, or whether the replacement might in turn might introduce strict pointer safety into the program.</p>
   <p>Further, according to <strong>[expr.new]</strong> ❡12, "An implementation is allowed to omit a call to a replaceable global allocation function. When it does so, the storage is instead provided by the implementation or provided by extending the allocation of another new-expression." If this is intended that these extended allocations be constrained to return a safely pointer on implementations with strict pointer safety, a note (if not normative text) would be helpful.</p>
   <h3 class="heading settled" data-level="4.4" id="constexpr"><span class="secno">4.4. </span><span class="content"><code class="highlight"><c- k>constexpr</c-></code> Allocation</span><a class="self-link" href="#constexpr"></a></h3>
   <p>Does compile-time (<code class="highlight"><c- k>constexpr</c-></code>) allocation by the language have strict, relaxed, or preferred memory safety? In practice, the current answer is largely irrelevant, as the only supported compile-time allocators call the global <code class="highlight"><c- o>::</c-><c- k>operator</c-> <c- k>new</c-></code> function, which by definition returns safely-derived pointers. Similarly, the masking and unmasking operations that might produce non-safely-derived pointers are not supported during constant evaluation. However, do note that the library facilities for handling pointer safety are not marked as <code class="highlight"><c- k>constexpr</c-></code>, so any library containers that make an effort to tune for performance on a garbage collected implementation must also guard such calls with a check for if (<code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>is_constant_evaluated</c-><c- p>()</c-></code>), genuinely avoid pointer masking tricks, and prepare for <a data-link-type="biblio" href="#biblio-p1974r0">[P1974R0]</a> Non-transient <code class="highlight"><c- k>constexpr</c-></code> allocation using <code class="highlight"><c- n>propconst</c-></code> providing support for <code class="highlight"><c- k>constinit</c-></code> objects allocated at compile-time, but used and extended at runtime.</p>
   <h3 class="heading settled" data-level="4.5" id="corelib"><span class="secno">4.5. </span><span class="content">Core versus Library Wording</span><a class="self-link" href="#corelib"></a></h3>
   <p>The core language talks about traceable pointer <em>objects</em> while the library uses the term traceable pointer <em>location</em>. This latter term is never defined, although the inference from cross-references is that they may be intended to mean the same thing. We should use the core term throughout the library as well, or more clearly define their relationship if distinct terms are intended.</p>
   <p>Our current best guess is that the two terms are intended to be distinct. From the usage in <strong>[util.dynamic.safety]</strong> ❡11, it seems that a traceable pointer location is a possible property of the value stored in a traceable pointer object, such that all traceable pointer objects assume the traceable pointer location property unless <code class="highlight"><c- n>declare_no_pointers</c-></code> is called.</p>
   <h3 class="heading settled" data-level="4.6" id="CHAR_BIT"><span class="secno">4.6. </span><span class="content"><code class="highlight"><c- b>signed</c-> <c- b>char</c-></code> and <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>byte</c-></code></span><a class="self-link" href="#CHAR_BIT"></a></h3>
   <p>According to <strong>[basic.stc.dynamic.safety]</strong> ❡3, a <em>traceable pointer object</em> may be "a sequence of elements in an array of narrow character type, where the size and alignment of the sequence match those of some object pointer type." This seems reasonable for types <code class="highlight"><c- b>char</c-></code> and <code class="highlight"><c- b>unsigned</c-> <c- b>char</c-></code>, which have special dispensation to be trafficked as raw memory. However, it may be more surprising to find this applies to arrays of <code class="highlight"><c- b>signed</c-> <c- b>char</c-></code> and <code class="highlight"><c- b>char8_t</c-></code> as well, which other than in this one paragraph, have no such memory aliasing properties. Similarly, it is surprising that arrays of <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>byte</c-></code>, a type deliberately introduced to describe raw memory, do not have this property.</p>
   <h3 class="heading settled" data-level="4.7" id="prefer"><span class="secno">4.7. </span><span class="content">Preferred Pointer Safety</span><a class="self-link" href="#prefer"></a></h3>
   <p>A call to <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>get_pointer_safety</c-></code> can return a value indicating <code class="highlight"><c- n>strict</c-></code>, <code class="highlight"><c- n>relaxed</c-></code>, or <code class="highlight"><c- n>preferred</c-></code>. It is not clear what the difference between <code class="highlight"><c- n>preferred</c-></code> and <code class="highlight"><c- n>relaxed</c-></code> memory safety is. From a core wording perspective, there is no difference, so the domain of well-defined behavior does not change. Other than this one mention on the specification for the <code class="highlight"><c- n>get_pointer_safety</c-></code> there is no description of what it means, and how programs should behave differently when informed of this. It appears to raise confusion, for no clear benefit. For example, should a program with concerns about <code class="highlight"><c- n>strict</c-></code> pointer safety check that an implementation has <code class="highlight"><c- n>relaxed</c-></code> pointer safety, or merely that it does not have <code class="highlight"><c- n>strict</c-></code> pointer safety? While these two questions are equivalent according to the core language specification, they can produce different results when querying the library API intended for this purpose.</p>
   <h3 class="heading settled" data-level="4.8" id="c"><span class="secno">4.8. </span><span class="content">C Compatibility</span><a class="self-link" href="#c"></a></h3>
   <p>Despite a decade of standards since C++11 (C11, C18, and the pending C2X), there has been no enthusiasm in WG14 to add similar garbage collection support to the C language.</p>
   <h3 class="heading settled" data-level="4.9" id="malloc"><span class="secno">4.9. </span><span class="content"><code class="highlight"><c- n>malloc</c-></code> and Related Functions</span><a class="self-link" href="#malloc"></a></h3>
   <p>In order to achieve binary compatibility with C code, an implementation must assume that all memory returned from a call to a C allocation function is implicitly declared reachable. It is not clear how this differs from being a safely-derived pointer, as a pointer to an object that has been declared reachable is never treated as invalid due to not being safely-derived. We suspect the intent is that such memory is to be treated similarly to that for automatic, static, and thread-local storage duration objects, other than the obscure normative text that says such pointers can be passed to <code class="highlight"><c- n>declare_unreachable</c-></code> which must somehow contrive to support this, and most likely ignore that pointer in such cases. This seems an obscurely specific way to permit a subset of pointers to be validly passed to a function that has no business seeing them. It would be much simpler to make the precondition on <code class="highlight"><c- n>declare_unreachable</c-></code> that there be a matching call to <code class="highlight"><c- n>declare_reachable</c-></code>, or to use another term to describe the reachability that comes from a call to the C allocation APIs.</p>
   <h2 class="heading settled" data-level="5" id="rationale"><span class="secno">5. </span><span class="content">Rationale</span><a class="self-link" href="#rationale"></a></h2>
   <p>Based on the above history, Garbage Collection in C++ is clearly useful for particular applications.</p>
   <p>However, Garbage Collection as specified by the Standard is not useful for those applications. In fact, the authors are not aware of any implementations of the strict pointer safety facility. Unsurprisingly, the authors are not aware of any uses either. Indeed, <a href="https://codesearch.isocpp.org/">ISOCpp code search only finds hits in GCC and LLVM</a>. Similarly, <a href="https://en.cppreference.com/w/cpp/compiler_support#cpp11">CppReference tells us</a> that implementations all offer no support for this feature. Finally, the specification falls short in many ways as outlined above.</p>
   <p>It’s unclear whether the Standard should make Garbage Collection an (optional?) first-class feature, because the aforementioned language VMs function differently from each other. What is clear is that the current specification isn’t helpful for any of them. The library facilities are clearly unused. The Core wording intends to offer minimal guarantees for garbage collectors, but doesn’t actually provide any actionable guidance to implementations, even if "strict" pointer safety were offered. Even then, libc++, libstdc++, and Microsoft’s Standard Library <a href="https://godbolt.org/z/ANaGAH">all offer relaxed pointer safety and not strict pointer safety</a>. In other words, the Core wording currently provides no restrictions on implementations, and the implementations nonetheless decided to go for the weaker "relaxed" option. Further, garbage collectors rely on other quality-of-implementations factors which Core wording is silent on.</p>
   <p>Finally, existing Standard Library implementations would need to be significantly changed were they to attempt supporting strict pointer safety, for example by marking regions memory pointer-free with <code class="highlight"><c- n>declare_no_pointers</c-></code> in containers such as <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>vector</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-></code>. Asking a Standard Library implementation to provide good support for strict pointer safety is tantamount to doubling the number of dialects that should be supported (including existing unofficial dialects such as without exceptions and type information).</p>
   <p>This status-quo hasn’t changed in 12 years. The maintenance burden on the Standard is near minimal, and we hope the Committee spends almost no time agreeing to remove this unused and unimplemented feature, despite its origins being well-intended and the target use-case still being relevant. Indeed, the current specification simply missed the mark, and will not be missed.</p>
   <p>We therefore propose outright removal instead of deprecation because lack of implementation and usage makes deprecation moot.</p>
   <h2 class="heading settled" data-level="6" id="other"><span class="secno">6. </span><span class="content">Other Concerns</span><a class="self-link" href="#other"></a></h2>
   <p>There are several other features in C++ that deal with the validity of pointers, or allocating memory. After some consideration, the following features were reviewed, but determined to have no impact on the strict pointer safety model. They are listed here so that the reader is aware that they were not overlooked.</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>launder</c-></code></p>
    <li data-md>
     <p>allocation for coroutines</p>
    <li data-md>
     <p>allocation for exception objects</p>
   </ul>
   <h2 class="heading settled" data-level="7" id="proposal"><span class="secno">7. </span><span class="content">Proposal</span><a class="self-link" href="#proposal"></a></h2>
   <p>Remove all of <strong>[basic.stc.dynamic.safety]</strong> as follows:</p>
   <blockquote>
    <del>
      A <em>traceable pointer object</em> is 
     <ul>
      <li data-md>
       <p>an object of an object pointer type, or</p>
      <li data-md>
       <p>an object of an integral type that is at least as large as <code class="highlight"><c- n>std</c-><c- o>::</c-><c- b>intptr_t</c-></code>, or</p>
      <li data-md>
       <p>a sequence of elements in an array of narrow character type, where the size and alignment of the sequence match those of some object pointer type.</p>
     </ul>
    </del>
    <del>
     A pointer value is a <em>safely-derived pointer</em> to an object with dynamic storage duration only if the pointer value has an object pointer type and is one of the following: 
     <ul>
      <li data-md>
       <p>the value returned by a call to the C++ standard library implementation of <code class="highlight"><c- o>::</c-><c- k>operator</c-> <c- k>new</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- b>size_t</c-><c- p>)</c-></code> or <code class="highlight"><c- o>::</c-><c- k>operator</c-> <c- k>new</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- b>size_t</c-><c- p>,</c-> <c- n>std</c-><c- o>::</c-><c- n>align_val_t</c-><c- p>)</c-></code></p>
      <li data-md>
       <p>the result of taking the address of an object (or one of its subobjects) designated by an lvalue resulting from indirection through a safely-derived pointer value;</p>
      <li data-md>
       <p>the result of well-defined pointer arithmetic using a safely-derived pointer value;</p>
      <li data-md>
       <p>the result of a well-defined pointer conversion of a safely-derived pointer value;</p>
      <li data-md>
       <p>the result of a <code class="highlight"><c- k>reinterpret_cast</c-></code> of a safely-derived pointer value;</p>
      <li data-md>
       <p>the result of a <code class="highlight"><c- k>reinterpret_cast</c-></code> of an integer representation of a safely-derived pointer value;</p>
      <li data-md>
       <p>the value of an object whose value was copied from a traceable pointer object, where at the time of the copy the source object contained a copy of a safely-derived pointer value.</p>
     </ul>
    </del>
    <del>
      An integer value is an <em>integer representation of a safely-derived pointer</em> only if its type is at least as large as <code class="highlight"><c- n>std</c-><c- o>::</c-><c- b>intptr_t</c-></code> and it is one of the following: 
     <ul>
      <li data-md>
       <p>the result of a <code class="highlight"><c- k>reinterpret_cast</c-></code> of a safely-derived pointer value;</p>
      <li data-md>
       <p>the result of a valid conversion of an integer representation of a safely-derived pointer value;</p>
      <li data-md>
       <p>the value of an object whose value was copied from a traceable pointer object, where at the time of the copy the source object contained an integer representation of a safely-derived pointer value;</p>
      <li data-md>
       <p>the result of an additive or bitwise operation, one of whose operands is an integer representation of a safely-derived pointer value <code class="highlight"><c- n>P</c-></code>, if that result converted by <code class="highlight"><c- k>reinterpret_cast</c-><c- o>&lt;</c-><c- b>void</c-><c- o>*></c-></code> would compare equal to a safely-derived pointer computable from <code class="highlight"><c- k>reinterpret_cast</c-><c- o>&lt;</c-><c- b>void</c-><c- o>*></c-><c- p>(</c-><c- n>P</c-><c- p>)</c-></code>.</p>
     </ul>
    </del>
    <del> An implementation may have <code class="highlight"><c- n>relaxed</c-> <c- n>pointer</c-> <c- n>safety</c-></code>, in which case the validity of a pointer value does not depend on whether it is a safely-derived pointer value. Alternatively, an implementation may have <code class="highlight"><c- n>strict</c-> <c- n>pointer</c-> <c- n>safety</c-></code>, in which case a pointer value referring to an object with dynamic storage duration that is not a safely-derived pointer value is an invalid pointer value unless the referenced complete object has previously been declared reachable. [<em>Note:</em> The effect of using an invalid pointer value (including passing it to a deallocation function) is undefined. This is true even if the unsafely-derived pointer value might compare equal to some safely-derived pointer value. — <em>end note</em> ] It is implementation defined whether an implementation has relaxed or strict pointer safety. </del>
   </blockquote>
   <p>In <strong>[expr.reinterpret.cast]</strong>, remove the note as follows:</p>
   <blockquote>
     A value of integral type or enumeration type can be explicitly converted to a pointer. A pointer converted to an integer of sufficient size (if any such exists on the implementation) and back to the same pointer type will have its original value; mappings between pointers and integers are otherwise implementation-defined. 
    <del>[<em>Note:</em> Except as described in <strong>[basic.stc.dynamic.safety]</strong>, the result of such a conversion will not be a safely-derived pointer value.
— <em>end note</em> ]</del>
   </blockquote>
   <p>In <strong>[new.delete]</strong>, remove the six instances of the pointer safety precondition on <code class="highlight"><c- k>operator</c-> <c- k>delete</c-></code> overloads as follows:</p>
   <blockquote>
<pre class="highlight"><code class="highlight"><c- b><c- b>void</c-></c-> <c- k><c- k>operator</c-></c-> <c- nf><c- nf>delete</c-></c-><c- p><c- p>(</c-></c-><c- b><c- b>void</c-></c-><c- o><c- o>*</c-></c-> <c- n><c- n>ptr</c-></c-><c- p><c- p>)</c-></c-> <c- k><c- k>noexcept</c-></c-><c- p><c- p>;</c-></c->
<c- b><c- b>void</c-></c-> <c- k><c- k>operator</c-></c-> <c- nf><c- nf>delete</c-></c-><c- p><c- p>(</c-></c-><c- b><c- b>void</c-></c-><c- o><c- o>*</c-></c-> <c- n><c- n>ptr</c-></c-><c- p><c- p>,</c-></c-> <c- n><c- n>std</c-></c-><c- o><c- o>::</c-></c-><c- b><c- b>size_t</c-></c-> <c- n><c- n>size</c-></c-><c- p><c- p>)</c-></c-> <c- k><c- k>noexcept</c-></c-><c- p><c- p>;</c-></c->
<c- b><c- b>void</c-></c-> <c- k><c- k>operator</c-></c-> <c- nf><c- nf>delete</c-></c-><c- p><c- p>(</c-></c-><c- b><c- b>void</c-></c-><c- o><c- o>*</c-></c-> <c- n><c- n>ptr</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>align_val_t</c-></c-> <c- n><c- n>alignment</c-></c-><c- p><c- p>)</c-></c-> <c- k><c- k>noexcept</c-></c-><c- p><c- p>;</c-></c->
<c- b><c- b>void</c-></c-> <c- k><c- k>operator</c-></c-> <c- nf><c- nf>delete</c-></c-><c- p><c- p>(</c-></c-><c- b><c- b>void</c-></c-><c- o><c- o>*</c-></c-> <c- n><c- n>ptr</c-></c-><c- p><c- p>,</c-></c-> <c- n><c- n>std</c-></c-><c- o><c- o>::</c-></c-><c- b><c- b>size_t</c-></c-> <c- n><c- n>size</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>align_val_t</c-></c-> <c- n><c- n>alignment</c-></c-><c- p><c- p>)</c-></c-> <c- k><c- k>noexcept</c-></c-><c- p><c- p>;</c-></c->

<c- b><c- b>void</c-></c-> <c- k><c- k>operator</c-></c-> <c- nf><c- nf>delete</c-></c-><c- p><c- p>(</c-></c-><c- b><c- b>void</c-></c-><c- o><c- o>*</c-></c-> <c- n><c- n>ptr</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>nothrow_t</c-></c-><c- o><c- o>&amp;</c-></c-><c- p><c- p>)</c-></c-> <c- k><c- k>noexcept</c-></c-><c- p><c- p>;</c-></c->
<c- b><c- b>void</c-></c-> <c- k><c- k>operator</c-></c-> <c- nf><c- nf>delete</c-></c-><c- p><c- p>(</c-></c-><c- b><c- b>void</c-></c-><c- o><c- o>*</c-></c-> <c- n><c- n>ptr</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>align_val_t</c-></c-> <c- n><c- n>alignment</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>nothrow_t</c-></c-><c- o><c- o>&amp;</c-></c-><c- p><c- p>)</c-></c-> <c- k><c- k>noexcept</c-></c-><c- p><c- p>;</c-></c->

<c- b><c- b>void</c-></c-> <c- k><c- k>operator</c-></c-> <c- k><c- k>delete</c-></c-><c- p><c- p>[](</c-></c-><c- b><c- b>void</c-></c-><c- o><c- o>*</c-></c-> <c- n><c- n>ptr</c-></c-><c- p><c- p>)</c-></c-> <c- k><c- k>noexcept</c-></c-><c- p><c- p>;</c-></c->
<c- b><c- b>void</c-></c-> <c- k><c- k>operator</c-></c-> <c- k><c- k>delete</c-></c-><c- p><c- p>[](</c-></c-><c- b><c- b>void</c-></c-><c- o><c- o>*</c-></c-> <c- n><c- n>ptr</c-></c-><c- p><c- p>,</c-></c-> <c- n><c- n>std</c-></c-><c- o><c- o>::</c-></c-><c- b><c- b>size_t</c-></c-> <c- n><c- n>size</c-></c-><c- p><c- p>)</c-></c-> <c- k><c- k>noexcept</c-></c-><c- p><c- p>;</c-></c->
<c- b><c- b>void</c-></c-> <c- k><c- k>operator</c-></c-> <c- k><c- k>delete</c-></c-><c- p><c- p>[](</c-></c-><c- b><c- b>void</c-></c-><c- o><c- o>*</c-></c-> <c- n><c- n>ptr</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>align_val_t</c-></c-> <c- n><c- n>alignment</c-></c-><c- p><c- p>)</c-></c-> <c- k><c- k>noexcept</c-></c-><c- p><c- p>;</c-></c->
<c- b><c- b>void</c-></c-> <c- k><c- k>operator</c-></c-> <c- k><c- k>delete</c-></c-><c- p><c- p>[](</c-></c-><c- b><c- b>void</c-></c-><c- o><c- o>*</c-></c-> <c- n><c- n>ptr</c-></c-><c- p><c- p>,</c-></c-> <c- n><c- n>std</c-></c-><c- o><c- o>::</c-></c-><c- b><c- b>size_t</c-></c-> <c- n><c- n>size</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>align_val_t</c-></c-> <c- n><c- n>alignment</c-></c-><c- p><c- p>)</c-></c-> <c- k><c- k>noexcept</c-></c-><c- p><c- p>;</c-></c->

<c- b><c- b>void</c-></c-> <c- k><c- k>operator</c-></c-> <c- k><c- k>delete</c-></c-><c- p><c- p>[](</c-></c-><c- b><c- b>void</c-></c-><c- o><c- o>*</c-></c-> <c- n><c- n>ptr</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>nothrow_t</c-></c-><c- o><c- o>&amp;</c-></c-><c- p><c- p>)</c-></c-> <c- k><c- k>noexcept</c-></c-><c- p><c- p>;</c-></c->
<c- b><c- b>void</c-></c-> <c- k><c- k>operator</c-></c-> <c- k><c- k>delete</c-></c-><c- p><c- p>[](</c-></c-><c- b><c- b>void</c-></c-><c- o><c- o>*</c-></c-> <c- n><c- n>ptr</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>align_val_t</c-></c-> <c- n><c- n>alignment</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>nothrow_t</c-></c-><c- o><c- o>&amp;</c-></c-><c- p><c- p>)</c-></c-> <c- k><c- k>noexcept</c-></c-><c- p><c- p>;</c-></c->

<c- b><c- b>void</c-></c-> <c- k><c- k>operator</c-></c-> <c- nf><c- nf>delete</c-></c-><c- p><c- p>(</c-></c-><c- b><c- b>void</c-></c-><c- o><c- o>*</c-></c-> <c- n><c- n>ptr</c-></c-><c- p><c- p>,</c-></c-> <c- b><c- b>void</c-></c-><c- o><c- o>*</c-></c-><c- p><c- p>)</c-></c-> <c- k><c- k>noexcept</c-></c-><c- p><c- p>;</c-></c->

<c- b><c- b>void</c-></c-> <c- k><c- k>operator</c-></c-> <c- k><c- k>delete</c-></c-><c- p><c- p>[](</c-></c-><c- b><c- b>void</c-></c-><c- o><c- o>*</c-></c-> <c- n><c- n>ptr</c-></c-><c- p><c- p>,</c-></c-> <c- b><c- b>void</c-></c-><c- o><c- o>*</c-></c-><c- p><c- p>)</c-></c-> <c- k><c- k>noexcept</c-></c-><c- p><c- p>;</c-></c->
</code></pre>
    <del><em>Preconditions:</em> If an implementation has strict pointer safety <strong>[basic.stc.dynamic.safety]</strong> then ptr is a safely-derived pointer.</del>
   </blockquote>
   <p>In <strong>[memory.syn]</strong>, remove as follows:</p>
   <blockquote>
<pre class="highlight"><code class="highlight"><del><c- c1><c- c1>// 20.10.5, pointer safety</c-></c->
<c- k><c- k>enum</c-></c-> <c- k><c- k>class</c-></c-> <c- nc><c- nc>pointer_safety</c-></c-> <c- p><c- p>{</c-></c-> <c- n><c- n>relaxed</c-></c-><c- p><c- p>,</c-></c-> <c- n><c- n>preferred</c-></c-><c- p><c- p>,</c-></c-> <c- n><c- n>strict</c-></c-> <c- p><c- p>};</c-></c->
<c- b><c- b>void</c-></c-> <c- nf><c- nf>declare_reachable</c-></c-><c- p><c- p>(</c-></c-><c- b><c- b>void</c-></c-><c- o><c- o>*</c-></c-> <c- n><c- n>p</c-></c-><c- p><c- p>);</c-></c->
<c- k><c- k>template</c-></c-><class t>
<c- n><c- n>T</c-></c-><c- o><c- o>*</c-></c-> <c- nf><c- nf>undeclare_reachable</c-></c-><c- p><c- p>(</c-></c-><c- n><c- n>T</c-></c-><c- o><c- o>*</c-></c-> <c- n><c- n>p</c-></c-><c- p><c- p>);</c-></c->
<c- b><c- b>void</c-></c-> <c- nf><c- nf>declare_no_pointers</c-></c-><c- p><c- p>(</c-></c-><c- b><c- b>char</c-></c-><c- o><c- o>*</c-></c-> <c- n><c- n>p</c-></c-><c- p><c- p>,</c-></c-> <c- b><c- b>size_t</c-></c-> <c- n><c- n>n</c-></c-><c- p><c- p>);</c-></c->
<c- b><c- b>void</c-></c-> <c- nf><c- nf>undeclare_no_pointers</c-></c-><c- p><c- p>(</c-></c-><c- b><c- b>char</c-></c-><c- o><c- o>*</c-></c-> <c- n><c- n>p</c-></c-><c- p><c- p>,</c-></c-> <c- b><c- b>size_t</c-></c-> <c- n><c- n>n</c-></c-><c- p><c- p>);</c-></c->
<c- n><c- n>pointer_safety</c-></c-> <c- nf><c- nf>get_pointer_safety</c-></c-><c- p><c- p>()</c-></c-> <c- k><c- k>noexcept</c-></c-><c- p><c- p>;</c-></c->
</class></del></code></pre>
   </blockquote>
   <p>Remove all of <strong>[util.dynamic.safety]</strong>, and associated implementation-defined behavior in the annex.</p>
   <p>In <strong>[cpp.predefined]</strong>, remove as follows:</p>
   <blockquote>
    <del><code class="highlight"><c- n>__STDCPP_STRICT_POINTER_SAFETY__</c-></code></del>
     <br> 
    <del>Defined, and has the value integer literal <code class="highlight"><c- mi>1</c-></code>, if and only if the implementation has strict pointer safety.</del>
   </blockquote>
   <p>In <strong>[c.malloc]</strong>, remove as follows:</p>
   <blockquote>
    <del> Storage allocated directly with these functions is implicitly declared reachable on allocation, ceases to be declared reachable on deallocation, and need not cease to be declared reachable as the result of an <code class="highlight"><c- n>undeclare_reachable</c-><c- p>()</c-></code> call. [ <em>Note:</em> This allows existing C libraries to remain unaffected by restrictions on pointers that are not safely derived, at the expense of providing far fewer garbage collection and leak detection options for <code class="highlight"><c- n>malloc</c-><c- p>()</c-></code>-allocated objects. It also allows <code class="highlight"><c- n>malloc</c-><c- p>()</c-></code> to be implemented with a separate allocation arena, bypassing the normal <code class="highlight"><c- n>declare_reachable</c-><c- p>()</c-></code> implementation. The above functions should never intentionally be used as a replacement for <code class="highlight"><c- n>declare_reachable</c-><c- p>()</c-></code>, and newly written code is strongly encouraged to treat memory allocated with these functions as though it were allocated with <code class="highlight"><c- k>operator</c-> <c- k>new</c-></code>. — <em>end note</em> ] </del>
   </blockquote>
   <p>In <strong>[zombie.names]</strong>, add the following names:</p>
   <blockquote>
    <ins>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>declare_reachable</c-></code></p>
      <li data-md>
       <p><code class="highlight"><c- n>undeclare_reachable</c-></code></p>
      <li data-md>
       <p><code class="highlight"><c- n>declare_no_pointers</c-></code></p>
      <li data-md>
       <p><code class="highlight"><c- n>undeclare_no_pointers</c-></code></p>
      <li data-md>
       <p><code class="highlight"><c- n>get_pointer_safety</c-></code></p>
      <li data-md>
       <p><code class="highlight"><c- n>pointer_safety</c-></code></p>
     </ul>
    </ins>
   </blockquote>
  </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-n2310">[N2310]
   <dd>H.-J. Boehm, M. Spertus. <a href="https://wg21.link/n2310">Transparent Programmer-Directed Garbage Collection for C++</a>. 20 June 2007. URL: <a href="https://wg21.link/n2310">https://wg21.link/n2310</a>
   <dt id="biblio-n2585">[N2585]
   <dd>H. Boehm, M. Spertus. <a href="https://wg21.link/n2585">Minimal Support for Garbage Collection and Reachability-Based Leak Detection</a>. 16 March 2008. URL: <a href="https://wg21.link/n2585">https://wg21.link/n2585</a>
   <dt id="biblio-n2670">[N2670]
   <dd>H.-J. Boehm, M. Spertus, C. Nelson. <a href="https://wg21.link/n2670">Minimal Support for Garbage Collection and Reachability-Based Leak Detection (revised)</a>. 13 June 2008. URL: <a href="https://wg21.link/n2670">https://wg21.link/n2670</a>
   <dt id="biblio-p1974r0">[P1974R0]
   <dd>Jeff Snyder, Louis Dionne, Daveed Vandevoorde. <a href="https://wg21.link/p1974r0">Non-transient constexpr allocation using propconst</a>. 15 May 2020. URL: <a href="https://wg21.link/p1974r0">https://wg21.link/p1974r0</a>
  </dl>