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

/* color variables included separately for reliability */

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

	html {
	}

	body {
		counter-reset: example figure issue;

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	p {
		margin: 1em 0;
	}

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

	/* Do something nice. */

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

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

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

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

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

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

	img {
		border-style: none;
	}

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


/*
Alternate table alignment rules

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

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

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

Possible extra rowspan handling

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

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

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


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

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

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

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

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

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

		.toc li {
			clear: both;
		}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

.outdated-warning span {
	display: block;
}

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

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

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

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

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



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

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

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

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

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

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

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

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

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

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

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

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

    --heading-text: #005a9c;

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

    --algo-border: #def;

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

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

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

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

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

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

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

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

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

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

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

    --datacell-border: silver;

    --indexinfo-text: #707070;

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

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

    --editedrec-bg: darkorange;
}
</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-issues */
a[href].issue-return {
    float: right;
    float: inline-end;
    color: var(--issueheading-text);
    font-weight: bold;
    text-decoration: none;
}
</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%;
}
.example > a.self-link,
.note > a.self-link,
.issue > a.self-link {
    /* These blocks are overflow:auto, so positioning outside
       doesn't work. */
    left: auto;
    right: 0;
}
li > a.self-link {
    left: calc(-1 * (3.5rem - 26px) - 2em);
}
dfn > a.self-link {
    top: auto;
    left: auto;
    opacity: 0;
    width: 1.5em;
    height: 1.5em;
    background: var(--selflink-bg);
    color: var(--selflink-text);
    font-style: normal;
    transition: opacity .2s, background-color .2s, color .2s;
}
dfn:hover > a.self-link {
    opacity: 1;
}
dfn > a.self-link:hover {
    color: var(--selflink-hover-text);
}

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

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

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

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

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

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

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

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

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

        --heading-text: #8af;

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

        --algo-border: #456;

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

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

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

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

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

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

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

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

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

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

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

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

        --datacell-border: silver;

        --indexinfo-text: #aaa;

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

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

        --editedrec-bg: darkorange;
    }
    /* In case a transparent-bg image doesn't expect to be on a dark bg,
       which is quite common in practice... */
    img { background: white; }
}

@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">R2771R1<br>Towards memory safety in C++</h1>
   <h2 class="no-num no-toc no-ref heading settled" id="profile-and-date"><span class="content">Draft Proposal, <time class="dt-updated" datetime="2023-05-17">2023-05-17</time></span></h2>
   <div data-fill-with="spec-metadata">
    <dl>
     <dt class="editor">Author:
     <dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:thomas.neumann@in.tum.de">Thomas Neumann</a> (<span class="p-org org">TUM</span>)
     <dt>Audience:
     <dd>EWG
     <dt>Project:
     <dd>ISO/IEC JTC1/SC22/WG21 14882: Programming Language — C++
     <dt>URL:
     <dd>https://wg21.link/R2771/1
     <dt>Source:
     <dd><a href="https://github.com/neumannt/memorysafety/blob/master/paper/memorysafety.bs">https://github.com/neumannt/memorysafety/blob/master/paper/memorysafety.bs</a>
     <dt>Date:
     <dd>2022-05-23
    </dl>
   </div>
   <div data-fill-with="warning"></div>
   <hr title="Separator for header">
  </div>
  <div class="p-summary" data-fill-with="abstract">
   <h2 class="no-num no-toc no-ref heading settled" id="abstract"><span class="content">Abstract</span></h2>
   <p>The lack of memory safety is one of the most concerning limitations of C++. This paper discusses a mechanism to make C++ memory safe while still keeping the traditional C++ programming concepts. By keeping track of dependencies between objects we can guarantee that an object will not be used after its dependencies have been destroyed or invalidated, which gives us temporal memory safety.</p>
  </div>
  <nav data-fill-with="table-of-contents" id="toc">
   <h2 class="no-num no-toc no-ref" id="contents">Table of Contents</h2>
   <ol class="toc" role="directory">
    <li><a href="#history"><span class="secno">1</span> <span class="content">Revision History</span></a>
    <li><a href="#intro"><span class="secno">2</span> <span class="content">Introduction</span></a>
    <li><a href="#concepts"><span class="secno">3</span> <span class="content">Concepts</span></a>
    <li>
     <a href="#compiletime"><span class="secno">4</span> <span class="content">Compile Time Checks</span></a>
     <ol class="toc">
      <li><a href="#aliasing"><span class="secno">4.1</span> <span class="content">Aliasing</span></a>
      <li><a href="#dependencies"><span class="secno">4.2</span> <span class="content">Dependency Tracking</span></a>
      <li><a href="#annotations"><span class="secno">4.3</span> <span class="content">Annotating Types</span></a>
      <li><a href="#interfaces"><span class="secno">4.4</span> <span class="content">Defining Interfaces</span></a>
     </ol>
    <li><a href="#dynamicchecks"><span class="secno">5</span> <span class="content">Runtime Checks</span></a>
    <li><a href="#multithreading"><span class="secno">6</span> <span class="content">Multi Threading</span></a>
    <li><a href="#openquestions"><span class="secno">7</span> <span class="content">Open Questions</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="history"><span class="secno">1. </span><span class="content">Revision History</span><a class="self-link" href="#history"></a></h2>
   <p>R1 more precise dependency declarations, separate compile time from runtime checks more clearly, discuss interfaces</p>
   <h2 class="heading settled" data-level="2" id="intro"><span class="secno">2. </span><span class="content">Introduction</span><a class="self-link" href="#intro"></a></h2>
   <p>The lack of memory safety in C++ is a serious concern, as it is a common cause for security vulnerabilities, which has led the U.S. government
to advise against using C++ for new projects. To stay relevant, C++ should evolve to guarantee memory safety by default (with explicit escape hatches to
allow for low-level programming techniques in the few cases these are needed).</p>
   <p>Historically C++ has already evolved to become safer, for example the introduction of smart pointers in C++11 eliminated large classes of
memory bugs. But unfortunately it is still very easy to construct a dangling pointer when passing pointers around. In fact some new additions
have made that even easier, for example constructing a (dangling) <code class="highlight"><c- n>string_view</c-></code> from a temporary <code class="highlight"><c- n>string</c-></code> is deceptively easy. That is very
unfortunate, the language should be safe by default. Some programs will still need a mechanism for potentially unsafe operations, for example when directly
interacting with hardware, but that should be an explicit opt-in, and limited to hopefully just a few places in the code that can then
be carefully checked for bugs.</p>
   <p>Sanitizer like, e.g., the address sanitizer supported by clang and gcc allow detecting many memory safety problems at runtime, but they
are no panacea. Consider the example code below:</p>
<pre class="highlight"><c- b>int</c-> <c- nf>main</c-><c- p>()</c-> <c- p>{</c->
   <c- n>string</c-> <c- n>s1</c-> <c- o>=</c-> <c- s>"abcdefg"</c-><c- p>;</c->
   <c- n>string_view</c-> <c- n>s2</c-> <c- o>=</c-> <c- n>s1</c-><c- p>;</c->
   <c- n>cout</c-> <c- o>&lt;&lt;</c-> <c- n>s2</c-><c- p>.</c-><c- n>length</c-><c- p>()</c-> <c- o>&lt;&lt;</c-> <c- s>" "</c-> <c- o>&lt;&lt;</c-> <c- n>s2</c-> <c- o>&lt;&lt;</c-> <c- n>endl</c-><c- p>;</c->
   <c- n>s1</c-><c- p>.</c-><c- n>erase</c-><c- p>(</c-><c- mi>2</c-><c- p>,</c-><c- mi>2</c-><c- p>);</c->
   <c- n>cout</c-> <c- o>&lt;&lt;</c-> <c- n>s2</c-><c- p>.</c-><c- n>length</c-><c- p>()</c-> <c- o>&lt;&lt;</c-> <c- s>" "</c-> <c- o>&lt;&lt;</c-> <c- n>s2</c-> <c- o>&lt;&lt;</c-> <c- n>endl</c-><c- p>;</c->
<c- p>}</c-></pre>
   <p>None of the currently sanitizers report a problem here, but it is clearly an example of unsafe behavior, as the second print produces garbage output. In the case of <code class="highlight"><c- n>string</c-></code> and <code class="highlight"><c- n>string_view</c-></code> that is still relatively benign, as we only print nonsense in that case. But we
could construct similar examples with <code class="highlight"><c- n>vector</c-></code> and <code class="highlight"><c- n>span</c-></code> where truly bad things would happen.
The difficulty that the sanitizers have is that they do not understand the semantics of the operations. The
underlying memory itself is still valid, but the contained objects have changed.</p>
   <p>There have been multiple proposals to improve the situation. The most radical one is to switch to another language, at least for new code,
in particular to Rust. Rust is famous for offering memory safety while still supporting low-level code like C++. Rust achieves this
using its borrow checker, which guarantees that 1) an object is not destroyed (or moved) while a reference to it exists, 2) there is at
most one mutable reference to an object, and 3) an object is not modified while a reference to it exists, except potentially through the
single mutable reference. This leads to code that is both safe and efficient, but it requires a programming model that is quite
different from what is commonly written in C++. And in general it is difficult to migrate an existing code base to Rust.
Rust is a great language with many nice features, but it is not well suited for piece wise replacement of C++ code. For that to be an option
there had to be a more or less seamless interaction between Rust and C++, but that is not the case. The lack of support for inheritance
in Rust makes accessing C++ objects problematic, and the programming patterns of Rust often look alien in C++.</p>
   <p>Less radical approaches suggest bringing lifetime annotations to C++, which would allow the compiler to detect frequent causes of bugs.
That is a good idea, but not sufficient for the general case. We want that the compiler guarantees memory safety, having a linter
that catches common problems is not good enough. Note that we will frequently only be able to guarantee memory safety in new code that
helps the compiler with proving that the code is safe. But that is okay as long as that code can be introduced piece by piece, since there
must be seamless interaction between the large existing code and new code.</p>
   <p>In particular, it is not an option to simply introduce the Rust borrow checker in C++. It is fundamentally incompatible with common
C++ idioms like, e.g., iterators. Enforcing the Rust rules would require a very different program style, and would not naturally
interact with existing code. Instead, we will introduce a different set of rules that guarantees memory safety, too, but that
is compatible with how current C++ code looks like. Sometimes the compiler will need annotations from the programmer to
allow for reasoning, but that should mainly affect library writers. Simple code should just work.
And existing code can seamlessly interact with the new code. It will not magically get the safety guarantees, of course, but
the code will work correctly, and code can migrate piece wise to the memory safe model.</p>
   <p>Note that the goal of this paper is mainly to show that it is possible to make C++ memory safe, and to discuss
the challenges in doing so. We take a first stab at a mechanism that can be used to reach that goal, fully aware that there
might be others that might work even better. Also, the syntax used here is pretty ad-hoc and not carefully designed,
this would require more work if the committee considers this approach interesting.
But what we want to emphasize is that full memory safety is possible, and we should not aim for less when changing the
language.</p>
   <p>Note further that this paper focuses on temporal memory safety, i.e., preventing access to destroyed objects and
preventing access to invalid object states. Spatial memory safety is required, too, but that can be
guaranteed with conceptually simpler mechanisms like, e.g., preventing raw pointer arithmetic in safe code, using <code class="highlight"><c- n>span</c-></code> with mandatory bounds checks instead, etc. We also have to forbid <code class="highlight"><c- k>reinterpret_cast</c-></code>, down-cast with <code class="highlight"><c- k>static_cast</c-></code> (<code class="highlight"><c- k>dynamic_cast</c-></code> is allowed), <code class="highlight"><c- k>const_cast</c-></code>, <code class="highlight"><c- k>mutable</c-></code>, plain <code class="highlight"><c- k>union</c-></code> (<code class="highlight"><c- n>variant</c-></code> is fine), and uninitialized pointers, as these break the type system.
These mechanisms will still be available in regions that are explicitly marked as unsafe (and that are hopefully carefully checked for
bugs).</p>
   <p>The approach presented here guarantees temporal memory safety by keeping track of dependencies. When an object A (e.g., a <code class="highlight"><c- n>reference_wrapper</c-></code>) depends
on an object B, we must not use A after B has been destroyed. We consider that a dependency on the existence of an object.
Similar, when an object A (e.g., a <code class="highlight"><c- n>string_view</c-></code> or an iterator) depends on the content of an object B, we must not use A after B has been modified.
We consider that a dependency on the content of an object. When we enforce both types of dependencies in the program we can guarantee temporal memory safety.</p>
   <p>We already have a proof-of-concept implementation that guarantees memory safety using dependency tracking <a data-link-type="biblio" href="#biblio-ms" title="Memory Safety Checks">[ms]</a>, but without compiler
support the dependencies have to be annotated and checked manually, which is undesirable. In the following we will therefore
introduce mechanisms to allow the compiler to reason about dependencies and reference aliases, which is essential to enforce the invariants described above automatically.</p>
   <h2 class="heading settled" data-level="3" id="concepts"><span class="secno">3. </span><span class="content">Concepts</span><a class="self-link" href="#concepts"></a></h2>
   <p>We assume that for a long time there will be mixture of memory safe and non memory safe code. Migrating an existing
code base takes a long time, and it has to be possible to do that incrementally. For simplicity, we assume that there
is some kind of opt-in mechanism like this mock syntax:</p>
<pre class="highlight"><c- k>namespace</c-> <c- nn>oldcode</c-> <c- p>{</c->
   <c- c1>// traditional C++ code</c->
<c- p>}</c->
<c- k>namespace</c-> <c- nn>newcode</c-> <c- p>{</c->
   <c- p>[[</c-><c- n>memorysafety</c-><c- p>]];</c->
   <c- c1>// everything defined in that scope enforces memory safety</c->
<c- p>}</c->
<c- k>namespace</c-> <c- nn>newcode</c-> <c- p>{</c->
   <c- c1>// not migrated yet, will not check memory safety, but can</c->
   <c- c1>// call everything from oldcode and newcode</c->
<c- p>}</c->
</pre>
   <p>In particular, the whole memory safety mechanism is opt-in in the sense that we get the same
memory layout and (at least conceptually) generate the same machine code
with and without memorysafety annotations, which is mandatory for piece wise migration. In particular, in the
example <code class="highlight"><c- n>oldcode</c-></code> can call <code class="highlight"><c- n>newcode</c-></code> without restrictions.</p>
   <p>Within the <code class="highlight"><c- n>memorysafety</c-></code> scope the compiler guarantees memory safety as long as we call only code
that is also marked with <code class="highlight"><c- n>memorysafety</c-></code>. When calling code that is not marked as memory safe all checks
are disabled and the result is assumed to be globally valid. To help with migration a compiler could emit
a warning for such a call.</p>
   <p>Within a memory safety region the compiler guarantees that no objects are used whose dependencies have been invalidated.
We distinguish two kinds of dependencies:</p>
   <ol>
    <li data-md>
     <p>a dependency on the __existance__ of an object. Typical example are pointers, we must not dereference a pointer that points to an destroyed object</p>
    <li data-md>
     <p>a dependency on the __content__ of an object. Typical examples are <code class="highlight"><c- n>string_view</c-></code> or iterators, we must not use a string view after then underlying string has been been modified (or destroyed).</p>
   </ol>
   <p>An object whose dependencies have been invalidated must not be used except for trivial destructors.
Note that this is weaker than the Rust borrow checker requirement, which mandates that
no reference to a destroyed object exists. But requiring that would be incompatible with C++ iterators,
as seen below:</p>
<pre class="highlight"><c- b>void</c-> <c- nf>foo</c-><c- p>(</c-><c- n>vector</c-><c- o>&lt;</c-><c- b>int</c-><c- o>>&amp;</c-> <c- n>a</c-><c- p>)</c-> <c- p>{</c->
   <c- k>if</c-> <c- p>(</c-><c- o>!</c-><c- n>a</c-><c- p>.</c-><c- n>empty</c-><c- p>())</c-> <c- p>{</c->
      <c- k>auto</c-> <c- n>i</c-> <c- o>=</c-> <c- n>a</c-><c- p>.</c-><c- n>begin</c-><c- p>();</c->
      <c- k>if</c-> <c- p>((</c-><c- o>*</c-><c- n>i</c-><c- p>)</c-> <c- o>&lt;</c-> <c- mi>5</c-><c- p>)</c-> <c- p>{</c->
         <c- n>a</c-><c- p>.</c-><c- n>push_back</c-><c- p>(</c-><c- mi>3</c-><c- p>);</c->
         <c- c1>// i is invalid now,</c->
         <c- c1>// but that is okay as long as i</c->
         <c- c1>// is not dereferenced</c->
      <c- p>}</c->
   <c- p>}</c->
<c- p>}</c->
</pre>
   <p>That is non-trivial to guarantee in general, thus we now discuss the mechanisms to
allow the compiler to reason about dependencies. We distinguish compile time checks
and runtime checks. We need both, unfortunately, for full memory safety, but common
programming mistakes can already be caught with pure compile time checks.
We assume a compiler will offer to switch between full memory safety and compile time
only checks for systems where the runtime overhead is unacceptable.</p>
   <h2 class="heading settled" data-level="4" id="compiletime"><span class="secno">4. </span><span class="content">Compile Time Checks</span><a class="self-link" href="#compiletime"></a></h2>
   <p>that we need for the compiler to deduce safety. We start with the problem of aliasing.
Note that in the following we will use the term reference to mean both pointers and
references. To simplify the discussion we also pretend as if every modification of
or access to of an object member happens through a corresponding access method. This
conceptual method could always be inlined, thus it is not a real restriction in practice.</p>
   <h3 class="heading settled" data-level="4.1" id="aliasing"><span class="secno">4.1. </span><span class="content">Aliasing</span><a class="self-link" href="#aliasing"></a></h3>
   <p>In order to reason about safety and the lifetime of objects, the
compiler must be able to detect if two references access the same object.
In current C++ code that is not the case in general. Consider the following example</p>
<pre class="highlight"><c- b>void</c-> <c- nf>foo</c-><c- p>(</c-><c- n>vector</c-><c- o>&lt;</c-><c- b>int</c-><c- o>>&amp;</c-> <c- n>a</c-><c- p>,</c-> <c- k>const</c-> <c- n>vector</c-><c- o>&lt;</c-><c- b>int</c-><c- o>>&amp;</c-> <c- n>b</c-><c- p>)</c-> <c- p>{</c->
   <c- k>if</c-> <c- p>(</c-><c- o>!</c-><c- n>b</c-><c- p>.</c-><c- n>empty</c-><c- p>())</c-> <c- p>{</c->
      <c- n>a</c-><c- p>.</c-><c- n>push_back</c-><c- p>(</c-><c- n>b</c-><c- p>.</c-><c- n>front</c-><c- p>());</c->
      <c- c1>// Unsafe, can crash when calling foo(x, x)</c->
   <c- p>}</c->
<c- p>}</c->
</pre>
   <p>The code looks innocent, but it is actually unsafe when <code class="highlight"><c- n>a</c-></code> and <code class="highlight"><c- n>b</c-></code> are aliasing each other.
We could add a check for that to <code class="highlight"><c- n>foo</c-></code>, but we want that code is safe by default. Thus, in memory
safe code, we introduce an aliasing requirement: <strong>When passing a non-const reference to a function or method, no other reference may alias that non-const reference</strong>.
Violations of that requirements are rejected by the compiler. Note that the implicit <code class="highlight"><c- k>this</c-></code> argument is a reference, too.</p>
   <p>Consider these examples, calling the function <code class="highlight"><c- n>foo</c-></code> from above:</p>
<pre class="highlight"><c- b>void</c-> <c- nf>bar</c-><c- p>(</c-><c- b>int</c-> <c- n>x</c-><c- p>,</c-> <c- b>int</c-> <c- n>y</c-><c- p>)</c-> <c- p>{</c->
   <c- n>vector</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-> <c- n>a</c-><c- p>,</c-> <c- n>b</c-><c- p>;</c->
   <c- n>array</c-><c- o>&lt;</c-><c- n>vector</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-><c- p>,</c-> <c- mi>2</c-><c- o>></c-> <c- n>c</c-><c- p>;</c->
   <c- n>foo</c-><c- p>(</c-><c- n>a</c-><c- p>,</c-><c- n>b</c-><c- p>);</c-> <c- c1>// ok</c->
   <c- n>foo</c-><c- p>(</c-><c- n>a</c-><c- p>,</c-><c- n>a</c-><c- p>);</c-> <c- c1>// error</c->
   <c- n>foo</c-><c- p>(</c-><c- n>c</c-><c- p>[</c-><c- n>x</c-><c- p>],</c-> <c- n>c</c-><c- p>[</c-><c- n>y</c-><c- p>]);</c-> <c- c1>// error, cannot prove that they do not alias</c->

   <c- k>auto</c-><c- o>&amp;</c-> <c- n>r1</c-> <c- o>=</c-> <c- o>&amp;</c-><c- n>c</c-><c- p>[</c-><c- n>x</c-><c- p>];</c->
   <c- k>auto</c-><c- o>&amp;</c-> <c- n>r2</c-> <c- o>=</c-> <c- o>&amp;</c-><c- n>c</c-><c- p>[</c-><c- n>y</c-><c- p>];</c->
   <c- k>if</c-> <c- p>(</c-><c- o>&amp;</c-><c- n>r1</c-> <c- o>!=</c-> <c- o>&amp;</c-><c- n>r2</c-><c- p>)</c->
      <c- n>foo</c-><c- p>(</c-><c- n>r1</c-><c- p>,</c-> <c- n>r2</c-><c- p>);</c-> <c- c1>// safe now</c->
<c- p>}</c->
</pre>
   <p>Alias analysis is essential for the rest of the memory safety proposal, as otherwise the compiler has no
chance to detect unsafe operations. However, we sometimes do want to allow aliasing, but that has to be
announced to the compiler:</p>
<pre class="highlight"><c- b>void</c-> <c- nf>swap</c-><c- p>(</c-><c- k>auto</c-><c- o>&amp;</c-> <c- n>a</c-><c- p>,</c-> <c- p>[[</c-><c- n>mayalias</c-><c- p>(</c-><c- n>a</c-><c- p>)]]</c-> <c- k>auto</c-><c- o>&amp;</c-> <c- n>b</c-><c- p>)</c-> <c- p>{</c-> <c- p>...</c-> <c- p>}</c->
</pre>
   <p>Now we can safely call <code class="highlight"><c- n>swap</c-></code> with potentially aliasing arguments and the compiler will make sure that <code class="highlight"><c- n>swap</c-></code> is safe even if <code class="highlight"><c- n>a</c-></code> and <code class="highlight"><c- n>b</c-></code> are the same object.</p>
   <p>Note that we made aliasing opt-in instead of opt-out as otherwise too much code breaks (a lot of code
is unsafe when arguments alias). And we explicitly list which arguments might alias each other, which
allows for more fine-grained reasoning.</p>
   <p>Note that the aliasing mechanism only tackles the problem of direct aliases. There are also more
subtle indirect aliasing (or rather: dependency) problems, as illustrated below, but these are caught by
the dependency tracking we discuss next:</p>
<pre class="highlight"><c- b>void</c-> <c- nf>foo</c-><c- p>(</c-><c- n>vector</c-><c- o>&lt;</c-><c- n>string</c-><c- o>>&amp;</c-> <c- n>a</c-><c- p>,</c-> <c- k>const</c-> <c- n>string</c-><c- o>&amp;</c-> <c- n>b</c-><c- p>)</c-> <c- p>{</c->
   <c- n>a</c-><c- p>.</c-><c- n>push_back</c-><c- p>(</c-><c- n>b</c-><c- p>);</c->
<c- p>}</c->
<c- b>void</c-> <c- nf>bar</c-><c- p>(</c-><c- n>vector</c-><c- o>&lt;</c-><c- n>string</c-><c- o>>&amp;</c-> <c- n>a</c-><c- p>)</c-> <c- p>{</c->
   <c- c1>// no direct alias, but nevertheless bad. Will be caught by dependencies</c->
   <c- n>foo</c-><c- p>(</c-><c- n>a</c-><c- p>,</c-> <c- n>a</c-><c- p>.</c-><c- n>front</c-><c- p>());</c->
<c- p>}</c->
</pre>
   <h3 class="heading settled" data-level="4.2" id="dependencies"><span class="secno">4.2. </span><span class="content">Dependency Tracking</span><a class="self-link" href="#dependencies"></a></h3>
   <p>Conceptually, we have to enforce a simple rule: A reference to an object must not be
dereferenced once the object has been destroyed. When we cannot be sure about all uses,
for example because the reference is stored outside a local variable, the reference
must not exist longer than the underlying object. This forces us to keep track of
lifetimes.</p>
   <p>Lifetimes are modeled as dependencies.
A global object has an infinite lifetime, i.e., every object can depend on a global object. (For now we ignore the problem of global constructor/destructor order, this might require more thoughts in the future).
A local object has a lifetime defined by its scope. When a local object is destroyed, all objects that depend upon that object must
a) have trivial destructors, and b) no methods must be called on the depending object.
Consider the example below:</p>
<pre class="highlight"><c- b>void</c-> <c- nf>foo</c-><c- p>()</c-> <c- p>{</c->
   <c- b>int</c-><c- o>*</c-> <c- n>a</c-><c- p>;</c->
   <c- p>{</c->
      <c- b>int</c-> <c- n>d</c-> <c- o>=</c-> <c- mi>2</c-><c- p>;</c->
      <c- n>a</c-> <c- o>=</c-> <c- o>&amp;</c-><c- n>d</c-><c- p>;</c-> <c- c1>// a depends on d</c->
      <c- o>*</c-><c- n>a</c-> <c- o>=</c-> <c- mi>3</c-><c- p>;</c-> <c- c1>// ok, d is alive</c->
   <c- p>}</c->
   <c- c1>// ok so far even though we have a dangling pointer</c->

   <c- c1>// would error: *a = 5; d is gone</c->
<c- p>}</c->
</pre>
   <p>When passing data from outside to a function we sometimes need explicit lifetime annotations.
If none are given, we require that the lifetime of no reference argument may depend on the
lifetime of a non-const reference argument (or non-const global). Consider the example below:</p>
<pre class="highlight"><c- b>void</c-> <c- nf>bar</c-><c- p>(</c-><c- b>int</c-><c- o>*</c-> <c- n>x</c-><c- p>),</c->
<c- b>void</c-> <c- n>foo</c-><c- p>(</c-><c- b>int</c-><c- o>&amp;</c-> <c- n>x</c-><c- p>,</c-> <c- b>int</c-><c- o>*&amp;</c-> <c- n>y</c-><c- p>)</c-> <c- p>{</c->
   <c- b>int</c-><c- o>*</c-> <c- n>a</c-> <c- o>=</c-> <c- o>&amp;</c-><c- n>x</c-><c- p>;</c-> <c- c1>// ok, a depends on x</c->
   <c- n>bar</c-><c- p>(</c-><c- n>a</c-><c- p>);</c-> <c- c1>// ok, x is alive</c->

   <c- c1>// error: y might live longer than x</c->
   <c- o>*</c-><c- n>y</c-> <c- o>=</c-> <c- n>a</c-><c- p>;</c->
<c- p>}</c->
</pre>
   <p>Here, we have to forbid the assignment to <code class="highlight"><c- n>y</c-></code> as we cannot guarantee that <code class="highlight"><c- n>y</c-></code> will not be
used after <code class="highlight"><c- n>x</c-></code> has been destroyed. If we want to allow that, we have to annotate the
function to propagate the dependency:</p>
<pre class="highlight"><c- b>void</c-> <c- nf>foo</c-><c- p>(</c-><c- b>int</c-><c- o>&amp;</c-> <c- n>x</c-><c- p>,</c-> <c- p>[[</c-><c- n>maycapture</c-><c- p>(</c-><c- o>&amp;</c-><c- n>x</c-><c- p>)]]</c-> <c- b>int</c-><c- o>*&amp;</c-> <c- n>y</c-><c- p>)</c-> <c- p>{</c->
   <c- c1>// ok, the caller can check the lifetimes of x and y</c->
   <c- o>*</c-><c- n>y</c-> <c- o>=</c-> <c- o>&amp;</c-><c- n>x</c-><c- p>;</c->
<c- p>}</c->
</pre>
   <p>For class methods we add a similar annotation if we store something that depends on a reference
argument, and we describe if the return value depends on function arguments:</p>
<pre class="highlight"><c- p>[[</c-><c- n>dependson</c-><c- p>(</c-><c- n>x</c-><c- p>,</c-><c- n>y</c-><c- p>)]]</c-> <c- b>char</c-><c- o>*</c-> <c- n>foo</c-><c- p>(</c-><c- b>char</c-><c- o>*</c-> <c- n>x</c-><c- p>,</c-> <c- b>char</c-><c- o>*</c-> <c- n>y</c-><c- p>)</c-> <c- p>{</c->
   <c- k>return</c-> <c- n>x</c-> <c- o>&lt;</c-> <c- n>y</c-> <c- o>?</c-> <c- n>x</c-> <c- o>:</c-> <c- n>y</c-><c- p>;</c->
<c- p>}</c->
<c- p>[[</c-><c- n>maycapture</c-><c- p>(</c-><c- n>x</c-><c- p>)]]</c-> <c- b>void</c-> <c- n>Foo</c-><c- o>::</c-><c- n>bar</c-><c- p>(</c-><c- b>int</c-><c- o>*</c-> <c- n>x</c-><c- p>)</c-> <c- p>{</c->
   <c- k>this</c-><c- o>-></c-><c- n>y</c-> <c- o>=</c-> <c- n>x</c-><c- p>;</c->
<c- p>}</c->
</pre>
   <p>These annotations allow us to detect when an object depends upon a destroyed object, but
they are not sufficient to handle, e.g., the <code class="highlight"><c- n>string_view</c-></code> example from the introduction.
There, the underlying <code class="highlight"><c- n>string</c-></code> still exists, but its state has changed. Similar for iterators,
we usually have to invalidate iterators when the underlying container has changed.
This can be annotated by capturing the __content__ of an object like this:</p>
<pre class="highlight"><c- p>[[</c-><c- n>dependson</c-><c- p>(</c-><c- o>*</c-><c- n>x</c-><c- p>)]]</c-> <c- n>string_view</c-> <c- n>foo</c-><c- p>(</c-><c- n>string</c-><c- o>&amp;</c-> <c- n>x</c-><c- p>)</c-> <c- p>{</c->
   <c- k>return</c-> <c- n>x</c-><c- p>;</c->
<c- p>}</c->
</pre>
   <p>This introduces a new rule: <strong>When an object A depends on the __content__ of an object B,
A must not be used after a non-const method of B has been invoked</strong>. Note that a non-trivial
destructor counts as use. This affects objects like <code class="highlight"><c- n>span</c-></code>, <code class="highlight"><c- n>string_view</c-></code>, and iterators that do
not own the underlying object, but that have to be invalidated when the underlying object is modified.</p>
   <p>Conceptually this is a simple rule that says that an object state is modified only by a non-const method,
thus all objects that depend upon the state of an object become invalid once a non-const method is invoked.
In practice there are some difficulties, though, as sometimes methods are intentionally non-const even though
they do not modify the state of an object. The most prominent ones are <code class="highlight"><c- n>begin</c-></code> and <code class="highlight"><c- n>end</c-></code>, which do not modify
the container itself, but that do provide non-const access to container elements. Clearly, we do not want
to invalidate all iterators when <code class="highlight"><c- n>begin</c-></code> or <code class="highlight"><c- n>end</c-></code> are called. Thus, we mark these functions as non-mutating,
i.e., keeping objects that depend on the content valid even though they are non-const.
The compiler must enforce that these functions do not call other non-const functions (except those marked as nonmutating):</p>
<pre class="highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- o>></c->
<c- p>[[</c-><c- n>dependson</c-><c- p>(</c-><c- o>*</c-><c- k>this</c-><c- p>),</c-><c- n>nonmutating</c-><c- p>]]</c-> <c- n>myvec</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>::</c-><c- n>iterator</c-> <c- n>myvec</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>::</c-><c- n>begin</c-><c- p>()</c-> <c- p>{</c->
   <c- k>return</c-> <c- n>iterator</c-><c- p>(</c-><c- k>this</c-><c- o>-></c-><c- n>ptr</c-><c- p>);</c->
<c- p>}</c->
</pre>
   <p>The third dependency rule that we introduce is that <strong>a function argument must not depend on another non-const function argument</strong>.
That rule allows us to detect the <code class="highlight"><c- n>a</c-><c- p>.</c-><c- n>push_back</c-><c- p>(</c-><c- n>a</c-><c- p>.</c-><c- n>front</c-><c- p>())</c-></code> example mentioned above. The result of <code class="highlight"><c- n>a</c-><c- p>.</c-><c- n>front</c-><c- p>()</c-></code> depends on the content of <code class="highlight"><c- n>a</c-></code>, which prevents it from being passed as an argument
to <code class="highlight"><c- n>a</c-><c- p>.</c-><c- n>push_back</c-><c- p>(...)</c-></code>.</p>
   <p>This formalism handles most use cases, but there is one kind of construct that is used in
the C++ standard library that is forbidden by the rules we have seen so far, and that is intentional
invalidation. Consider this example fragment with a call to <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>vector</c-><c- o>::</c-><c- n>insert</c-></code>:</p>
<pre class="highlight"><c- n>a</c-><c- p>.</c-><c- n>insert</c-><c- p>(</c-><c- n>a</c-><c- p>.</c-><c- n>end</c-><c- p>(),</c-> <c- n>b</c-><c- p>.</c-><c- n>begin</c-><c- p>(),</c-> <c- n>b</c-><c- p>.</c-><c- n>end</c-><c- p>());</c->
</pre>
   <p>Our dependency rules say that <code class="highlight"><c- n>b</c-><c- p>.</c-><c- n>begin</c-><c- p>()</c-></code> and <code class="highlight"><c- n>b</c-><c- p>.</c-><c- n>end</c-><c- p>()</c-></code> must not depend upon <code class="highlight"><c- n>a</c-></code>, and for good reasons. But the first argument to <code class="highlight"><c- n>insert</c-></code> is different, there
we do not only accept a dependency but we actually require that the iterator belongs
to the same container. In many cases we will not be able to prove that statically,
and implementing <code class="highlight"><c- n>insert</c-></code> itself is also tricky because the size change of the <code class="highlight"><c- n>vector</c-></code> invalidates the position iterator. For now we accept that implementing <code class="highlight"><c- n>insert</c-></code> requires unsafe code (and an assert to make sure that the iterator indeed references the vector)
and just introduce an annotation to allow this dependency:</p>
<pre class="highlight"><c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>InputIt</c-><c- o>></c->
<c- p>[[</c-><c- n>dependson</c-><c- p>(</c-><c- o>*</c-><c- k>this</c-><c- p>)]]</c-> <c- n>iterator</c-> <c- n>insert</c-><c- p>([[</c-><c- n>maydependon</c-><c- p>(</c-><c- o>*</c-><c- k>this</c-><c- p>)]]</c-> <c- n>const_iterator</c-> <c- n>pos</c-><c- p>,</c-> <c- n>InputIt</c-> <c- n>first</c-><c- p>,</c-> <c- n>InputIt</c-> <c- n>last</c-><c- p>);</c->
</pre>
   <h3 class="heading settled" data-level="4.3" id="annotations"><span class="secno">4.3. </span><span class="content">Annotating Types</span><a class="self-link" href="#annotations"></a></h3>
   <p>To automate the compile time checks, the compiler has to recognize the dependencies that occur within
a program. For that, we first need a notion of a dependency-carrying type, which we call a <code class="highlight"><c- n>reference</c-></code> here.
Regular pointers and references are implicitly considered a reference. User defined types must be annotated
as reference carrying if they capture dependencies:</p>
<pre class="highlight"><c- c1>// We need an annotation here</c->
<c- k>class</c-> <c- p>[[</c-><c- n>references</c-><c- p>]]</c-> <c- n>Class1</c-> <c- p>{</c->
   <c- n>Foo</c-><c- o>*</c-> <c- n>x</c-><c- p>;</c->
   <c- k>public</c-><c- o>:</c->
   <c- p>[[</c-><c- n>maycapture</c-><c- p>(</c-><c- n>nx</c-><c- p>)]]</c-> <c- b>void</c-> <c- n>set_x</c-><c- p>(</c-><c- n>Foo</c-><c- o>*</c-> <c- n>nx</c-><c- p>)</c-> <c- p>{</c-> <c- n>x</c-><c- o>=</c-><c- n>nx</c-><c- p>;</c-> <c- p>};</c->
   <c- p>...</c->
<c- p>};</c->
<c- c1>// No annotation is needed here, we do not capture</c->
<c- k>class</c-> <c- nc>Class2</c-> <c- p>{</c->
   <c- n>Foo</c-><c- o>*</c-> <c- n>pimpl</c-> <c- o>=</c-> <c- k>new</c-> <c- n>Foo</c-><c- p>();</c->
   <c- k>public</c-><c- o>:</c->
   <c- p>...</c->
<c- p>};</c->
</pre>
   <p>With that, the compiler recognizes objects that potentially depend on other objects whose lifetime they
do not control. This information is used for the three cases of capturing annotations:</p>
<pre class="highlight"><c- c1>// We make a copy of x</c->
<c- p>[[</c-><c- n>maycapture</c-><c- p>(</c-><c- n>x</c-><c- p>)]]</c-> <c- b>void</c-> <c- n>foo1</c-><c- p>(</c-><c- n>Foo</c-><c- o>&amp;</c-> <c- n>x</c-><c- p>);</c->
<c- c1>// We keep the address of x</c->
<c- p>[[</c-><c- n>maycapture</c-><c- p>(</c-><c- o>&amp;</c-><c- n>x</c-><c- p>)]]</c-> <c- b>void</c-> <c- n>foo2</c-><c- p>(</c-><c- n>Foo</c-><c- o>&amp;</c-> <c- n>x</c-><c- p>);</c->
<c- c1>// We keep the address of x and the content of x must not change</c->
<c- c1>// (e.g., because we store an iterator)</c->
<c- p>[[</c-><c- n>maycapture</c-><c- p>(</c-><c- o>*</c-><c- n>x</c-><c- p>)]]</c-> <c- b>void</c-> <c- n>foo3</c-><c- p>(</c-><c- n>Foo</c-><c- o>&amp;</c-> <c- n>x</c-><c- p>);</c->
</pre>
   <p>Note that the annotation of <code class="highlight"><c- n>foo1</c-></code> is a no-op if <code class="highlight"><c- n>x</c-></code> is not itself marked as reference, as capturing
a non-reference cannot create new dependencies. Nevertheless we need these annotations for generic
programming, as x might sometimes be a reference. Inversely, an object <code class="highlight"><c- n>a</c-></code> is only allowed to capture
an object <code class="highlight"><c- n>b</c-></code> if <code class="highlight"><c- n>a</c-></code> is marked as <code class="highlight"><c- n>references</c-></code>, as this tells the compiler to keep track of dependencies.</p>
   <h3 class="heading settled" data-level="4.4" id="interfaces"><span class="secno">4.4. </span><span class="content">Defining Interfaces</span><a class="self-link" href="#interfaces"></a></h3>
   <p>Dependency annotations are challenging when defining generic interfaces, like virtual functions, function pointers
or in generic programming. The first question is, should the dependency annotations be part of the type system?
That is, is the type of <code class="highlight"><c- b>void</c-> <c- n>foo</c-><c- p>(</c-><c- b>int</c-><c- o>**</c-> <c- n>a</c-><c- p>,</c-> <c- b>int</c-><c- o>&amp;</c-> <c- n>b</c-><c- p>)</c-></code> different from <code class="highlight"><c- b>void</c-> <c- n>bar</c-><c- p>([[</c-><c- n>maycapture</c-><c- p>(</c-><c- o>&amp;</c-><c- n>b</c-><c- p>)]]</c-> <c- b>int</c-><c- o>**</c-> <c- n>a</c-><c- p>,</c-> <c- b>int</c-><c- o>&amp;</c-> <c- n>b</c-><c- p>)</c-></code>?
From a safety perspective it makes sense to treat them differently, but if we allow overloading based upon
dependency annotations that clashes with the rule that it is safe to ignore all C++ attributes.
Thus, for now we do not consider them part of the type system when overloading, but the compiler should refuse
to cast a function type into another unless the capture set is a super set of the original captures.</p>
   <p>For virtual functions we have same behavior, it is permitted to capture less than the base class but not to capture more:</p>
<pre class="highlight"><c- k>class</c-> <c- p>[[</c-><c- n>references</c-><c- p>]]</c-> <c- n>Base</c-> <c- p>{</c->
   <c- p>[[</c-><c- n>maycapture</c-><c- p>(</c-><c- o>&amp;</c-><c- n>x</c-><c- p>)]]</c-> <c- k>virtual</c-> <c- b>void</c-> <c- n>foo</c-><c- p>(</c-><c- n>Foo</c-><c- o>&amp;</c-> <c- n>x</c-><c- p>,</c-> <c- n>Bar</c-><c- o>&amp;</c-> <c- n>y</c-><c- p>)</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c->
<c- p>};</c->
<c- k>class</c-> <c- nc>Derived1</c-> <c- o>:</c-> <c- k>public</c-> <c- n>Base</c-> <c- p>{</c->
   <c- p>[[</c-><c- n>maycapture</c-><c- p>(</c-><c- o>&amp;</c-><c- n>x</c-><c- p>)]]</c-> <c- b>void</c-> <c- n>foo</c-><c- p>(</c-><c- n>Foo</c-><c- o>&amp;</c-> <c- n>x</c-><c- p>,</c-> <c- n>Bar</c-><c- o>&amp;</c-> <c- n>y</c-><c- p>)</c-> <c- k>override</c-><c- p>;</c-> <c- c1>// ok, we capture the same</c->
<c- p>};</c->
<c- k>class</c-> <c- nc>Derived2</c-> <c- o>:</c-> <c- k>public</c-> <c- n>Base</c-> <c- p>{</c->
   <c- b>void</c-> <c- nf>foo</c-><c- p>(</c-><c- n>Foo</c-><c- o>&amp;</c-> <c- n>x</c-><c- p>,</c-> <c- n>Bar</c-><c- o>&amp;</c-> <c- n>y</c-><c- p>)</c-> <c- k>override</c-><c- p>;</c-> <c- c1>// ok, we capture less</c->
<c- p>};</c->
<c- k>class</c-> <c- nc>Derived3</c-> <c- o>:</c-> <c- k>public</c-> <c- n>Base</c-> <c- p>{</c->
   <c- p>[[</c-><c- n>maycapture</c-><c- p>(</c-><c- o>&amp;</c-><c- n>y</c-><c- p>)]]</c-> <c- b>void</c-> <c- n>foo</c-><c- p>(</c-><c- n>Foo</c-><c- o>&amp;</c-> <c- n>x</c-><c- p>,</c-> <c- n>Bar</c-><c- o>&amp;</c-> <c- n>y</c-><c- p>)</c-> <c- k>override</c-><c- p>;</c-> <c- c1>// error, we capture more or different</c->
<c- p>};</c->
</pre>
   <p>With generic programming we have the problem that we do not even know if the values that we are handling
carry dependencies themselves. To cover this, we extend the <code class="highlight"><c- p>[[</c-><c- n>references</c-><c- p>]]</c-></code> attribute into
a <code class="highlight"><c- p>[[</c-><c- n>references</c-><c- p>(</c-><c- n>A</c-><c- p>,</c-><c- n>B</c-><c- p>,</c-><c- n>C</c-><c- p>,...)]]</c-></code> attribute to express that the type is referencing another if any of the <code class="highlight"><c- n>A</c-><c- p>,</c-><c- n>B</c-><c- p>,</c-><c- n>C</c-><c- p>,...</c-></code> list
is a reference. With that, we can provide an interface for a generic vector, which shows the different annotations that we need:</p>
<pre class="highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- o>></c->
<c- k>class</c-> <c- p>[[</c-><c- n>references</c-><c- p>(</c-><c- n>T</c-><c- p>)]]</c-> <c- n>my_vec</c-> <c- p>{</c->
   <c- p>...</c->
   <c- c1>/// We copy x, which might or might not propagate a dependency</c->
   <c- p>[[</c-><c- n>maycapture</c-><c- p>(</c-><c- n>x</c-><c- p>))]]</c-> <c- b>void</c-> <c- n>push</c-><c- p>(</c-><c- k>const</c-> <c- n>T</c-><c- o>&amp;</c-> <c- n>x</c-><c- p>);</c->
   <c- p>...</c->
   <c- k>class</c-> <c- p>[[</c-><c- n>references</c-><c- p>]]</c-> <c- n>iterator</c-> <c- p>{</c-> <c- p>...</c-> <c- p>};</c->
   <c- p>...</c->
   <c- p>[[</c-><c- n>dependson</c-><c- p>(</c-><c- o>*</c-><c- k>this</c-><c- p>),</c-><c- n>nonmutating</c-><c- p>]]</c-> <c- n>iterator</c-> <c- n>begin</c-><c- p>();</c->
   <c- p>...</c->
<c- p>};</c->
</pre>
   <p>To summarize, the interface has to tell the compiler 1) what is a reference like type, and 2) when to we create or store a reference to what.
No annotations are needed when an argument is simply used inside a function and no reference escapes the call, which will be the
majority of function calls.</p>
   <h2 class="heading settled" data-level="5" id="dynamicchecks"><span class="secno">5. </span><span class="content">Runtime Checks</span><a class="self-link" href="#dynamicchecks"></a></h2>
   <p>For fully memory safety it is unfortunately unavoidable to perform some runtime checks, which we will discuss next.
In contrast to the compile time checks they cause runtime overhead, and thus it has to be possible to disable them.
Some users might only want to enable them in debug builds to find potential dependency violations, as that will
already find most problems in practice.</p>
   <p>The rules discussed so far are useful for catching many common temporal memory safety bugs, but they
are unfortunately not sufficient to catch all of them at compile time. Perhaps somewhat surprisingly,
the main challenge is not so much reasoning about lifetimes but aliasing. Consider this hypothetical code snippet below:</p>
<pre class="highlight"><c- b>void</c-> <c- nf>f1</c-><c- p>()</c-> <c- p>{</c->
   <c- n>A</c-> <c- n>a</c-><c- p>;</c->
   <c- n>B</c-> <c- n>b</c-><c- p>;</c->
   <c- n>C</c-> <c- n>c</c-><c- p>;</c->
   <c- n>a</c-><c- p>.</c-><c- n>push_back</c-><c- p>(</c-><c- mi>123</c-><c- p>);</c->
   <c- n>f2</c-><c- p>(</c-><c- n>a</c-><c- p>,</c-> <c- n>b</c-><c- p>,</c-> <c- n>c</c-><c- p>);</c->
   <c- n>f3</c-><c- p>(</c-><c- n>b</c-><c- p>);</c->
   <c- n>f4</c-><c- p>(</c-><c- n>c</c-><c- p>);</c->
   <c- n>f5</c-><c- p>(</c-><c- n>b</c-><c- p>);</c->
<c- p>}</c->
<c- b>void</c-> <c- nf>f2</c-><c- p>(</c-><c- n>A</c-><c- o>&amp;</c-> <c- n>a</c-><c- p>,</c-> <c- p>[[</c-><c- n>maycapture</c-><c- p>(</c-><c- o>&amp;</c-><c- n>a</c-><c- p>)]]</c-> <c- n>B</c-><c- o>&amp;</c-> <c- n>b</c-><c- p>,</c-> <c- p>[[</c-><c- n>maycapture</c-><c- p>(</c-><c- o>&amp;</c-><c- n>a</c-><c- p>)]]</c-> <c- n>C</c-><c- o>&amp;</c-> <c- n>c</c-><c- p>)</c-> <c- p>{</c->
   <c- n>b</c-><c- p>.</c-><c- n>a</c-><c- o>=&amp;</c-><c- n>a</c-><c- p>;</c->
   <c- n>c</c-><c- p>.</c-><c- n>a</c-><c- o>=&amp;</c-><c- n>a</c-><c- p>;</c->
<c- p>}</c->
<c- b>void</c-> <c- nf>f3</c-><c- p>(</c-><c- n>B</c-><c- o>&amp;</c-> <c- n>b</c-><c- p>)</c-> <c- p>{</c->
   <c- n>b</c-><c- p>.</c-><c- n>i</c-> <c- o>=</c-> <c- n>b</c-><c- p>.</c-><c- n>a</c-><c- o>-></c-><c- n>begin</c-><c- p>();</c->
<c- p>}</c->
<c- b>void</c-> <c- nf>f4</c-><c- p>(</c-><c- n>C</c-><c- o>&amp;</c-> <c- n>c</c-><c- p>)</c-> <c- p>{</c->
   <c- n>c</c-><c- p>.</c-><c- n>a</c-><c- o>-></c-><c- n>clear</c-><c- p>();</c->
<c- p>}</c->
<c- b>void</c-> <c- nf>f5</c-><c- p>(</c-><c- n>B</c-><c- o>&amp;</c-> <c- n>b</c-><c- p>)</c-> <c- p>{</c->
   <c- n>b</c-><c- p>.</c-><c- n>e</c-> <c- o>=</c-> <c- o>*</c-><c- n>b</c-><c- p>.</c-><c- n>i</c-><c- p>;</c->
<c- p>}</c->
</pre>
   <p>Considered in isolation, none of the functions violate any lifetime rules. <code class="highlight"><c- n>a</c-></code> outlives <code class="highlight"><c- n>b</c-></code> and <code class="highlight"><c- n>c</c-></code>, <code class="highlight"><c- n>f2</c-></code> is properly annotated as capturing,
and each function is harmless in itself. But the combination clearly violates memory safety because <code class="highlight"><c- n>f4</c-></code> invalidates the iterator
constructed in <code class="highlight"><c- n>f3</c-></code>, and the compiler has no chance to detect that, at least if the functions are defined in different compilation units,
as <code class="highlight"><c- n>b</c-></code> and <code class="highlight"><c- n>c</c-></code> are separate objects.
One could try to introduce very elaborate annotations to describe that behavior, but that does not seem to be practical and would cause huge
problems for generic code.</p>
   <p>But what we can do instead is to detect the problem at runtime. Conceptually a dependency is like a soft lock, the referenced object
must not end its lifetime before the dependent object. If it does, we consider the dependent object invalid, any operation except a trivial destructor
will trigger an assert (and terminate the program). Similar for dependencies on the content of an object, here a call to a non-const method
will invalidate the dependent objects. In a hypothetical memory-safety-sanitizer compilation the effective code could thus look as follows
(the sanitizer calls are here added outside the called methods instead of inside to keep the code size reasonable):</p>
<pre class="highlight"><c- b>void</c-> <c- nf>f1</c-><c- p>()</c-> <c- p>{</c->
   <c- n>A</c-> <c- n>a</c-><c- p>;</c->
   <c- n>B</c-> <c- n>b</c-><c- p>;</c->
   <c- n>C</c-> <c- n>c</c-><c- p>;</c->
   <c- n>memorysafety</c-><c- o>::</c-><c- n>mark_modified</c-><c- p>(</c-><c- o>&amp;</c-><c- n>a</c-><c- p>);</c->
   <c- n>a</c-><c- p>.</c-><c- n>push_back</c-><c- p>(</c-><c- mi>123</c-><c- p>);</c->
   <c- n>f2</c-><c- p>(</c-><c- n>a</c-><c- p>,</c-> <c- n>b</c-><c- p>,</c-> <c- n>c</c-><c- p>);</c->
   <c- n>f3</c-><c- p>(</c-><c- n>b</c-><c- p>);</c->
   <c- n>f4</c-><c- p>(</c-><c- n>c</c-><c- p>);</c->
   <c- n>f5</c-><c- p>(</c-><c- n>b</c-><c- p>);</c->
   <c- n>memorysafety</c-><c- o>::</c-><c- n>mark_destroyed</c-><c- p>(</c-><c- o>&amp;</c-><c- n>c</c-><c- p>);</c->
   <c- n>memorysafety</c-><c- o>::</c-><c- n>mark_destroyed</c-><c- p>(</c-><c- o>&amp;</c-><c- n>b</c-><c- p>.</c-><c- n>i</c-><c- p>);</c->
   <c- n>memorysafety</c-><c- o>::</c-><c- n>mark_destroyed</c-><c- p>(</c-><c- o>&amp;</c-><c- n>b</c-><c- p>);</c->
   <c- n>memorysafety</c-><c- o>::</c-><c- n>mark_destroyed</c-><c- p>(</c-><c- o>&amp;</c-><c- n>a</c-><c- p>);</c->
<c- p>}</c->
<c- b>void</c-> <c- nf>f2</c-><c- p>(</c-><c- n>A</c-><c- o>&amp;</c-> <c- n>a</c-><c- p>,</c-> <c- p>[[</c-><c- n>maycapture</c-><c- p>(</c-><c- o>&amp;</c-><c- n>a</c-><c- p>)]]</c-> <c- n>B</c-><c- o>&amp;</c-> <c- n>b</c-><c- p>,</c-> <c- p>[[</c-><c- n>maycapture</c-><c- p>(</c-><c- o>&amp;</c-><c- n>a</c-><c- p>)]]</c-> <c- n>C</c-><c- o>&amp;</c-> <c- n>c</c-><c- p>)</c-> <c- p>{</c->
   <c- n>memorysafety</c-><c- o>::</c-><c- n>add_dependency</c-><c- p>(</c-><c- o>&amp;</c-><c- n>b</c-><c- p>,</c-> <c- o>&amp;</c-><c- n>a</c-><c- p>);</c->
   <c- n>b</c-><c- p>.</c-><c- n>a</c-><c- o>=&amp;</c-><c- n>a</c-><c- p>;</c->
   <c- n>memorysafety</c-><c- o>::</c-><c- n>add_dependency</c-><c- p>(</c-><c- o>&amp;</c-><c- n>c</c-><c- p>,</c-> <c- o>&amp;</c-><c- n>a</c-><c- p>);</c->
   <c- n>c</c-><c- p>.</c-><c- n>a</c-><c- o>=&amp;</c-><c- n>a</c-><c- p>;</c->
<c- p>}</c->
<c- b>void</c-> <c- nf>f3</c-><c- p>(</c-><c- n>B</c-><c- o>&amp;</c-> <c- n>b</c-><c- p>)</c-> <c- p>{</c->
   <c- n>memorysafety</c-><c- o>::</c-><c- n>validate</c-><c- p>(</c-><c- n>b</c-><c- p>.</c-><c- n>a</c-><c- p>);</c->
   <c- n>memorysafety</c-><c- o>::</c-><c- n>add_content_dependency</c-><c- p>(</c-><c- o>&amp;</c-><c- n>b</c-><c- p>.</c-><c- n>i</c-><c- p>,</c-> <c- n>b</c-><c- p>.</c-><c- n>a</c-><c- p>);</c->
   <c- n>b</c-><c- p>.</c-><c- n>i</c-> <c- o>=</c-> <c- n>b</c-><c- p>.</c-><c- n>a</c-><c- o>-></c-><c- n>begin</c-><c- p>();</c->
<c- p>}</c->
<c- b>void</c-> <c- nf>f4</c-><c- p>(</c-><c- n>C</c-><c- o>&amp;</c-> <c- n>c</c-><c- p>)</c-> <c- p>{</c->
   <c- n>memorysafety</c-><c- o>::</c-><c- n>validate</c-><c- p>(</c-><c- n>c</c-><c- p>.</c-><c- n>a</c-><c- p>);</c->
   <c- n>memorysafety</c-><c- o>::</c-><c- n>mark_modified</c-><c- p>(</c-><c- n>c</c-><c- p>.</c-><c- n>a</c-><c- p>);</c->
   <c- n>c</c-><c- p>.</c-><c- n>a</c-><c- o>-></c-><c- n>clear</c-><c- p>();</c->
<c- p>}</c->
<c- b>void</c-> <c- nf>f5</c-><c- p>(</c-><c- n>B</c-><c- o>&amp;</c-> <c- n>b</c-><c- p>)</c-> <c- p>{</c->
   <c- n>memorysafety</c-><c- o>::</c-><c- n>validate</c-><c- p>(</c-><c- o>&amp;</c-><c- n>b</c-><c- p>.</c-><c- n>i</c-><c- p>);</c->
   <c- n>b</c-><c- p>.</c-><c- n>e</c-> <c- o>=</c-> <c- o>*</c-><c- n>b</c-><c- p>.</c-><c- n>i</c-><c- p>;</c->
<c- p>}</c->
</pre>
   <p>In that version the <code class="highlight"><c- n>validate</c-></code> call in <code class="highlight"><c- n>f5</c-></code> fails, correctly detecting that the content of <code class="highlight"><c- n>a</c-></code> has changed.</p>
   <p>A proof-of-concept implementation of this checking infrastructure is available online <a data-link-type="biblio" href="#biblio-ms" title="Memory Safety Checks">[ms]</a>.
Like a typical sanitizer it is implemented using associate data structures, the underlying
objects are left untouched. The implementation is not too expensive, <code class="highlight"><c- n>validate</c-></code> is in O(1), <code class="highlight"><c- n>mark_modified</c-></code> and <code class="highlight"><c- n>mark_destroyed</c-></code> are amortized in O(1), and the dependency functions are
logarithmic in the number of dependencies of an object. Nevertheless, these checks do cause
overhead, thus one would probably use them like a typical sanitizer, detecting dependency
bugs in debug builds and disabling the checks in release builds.</p>
   <p>The runtime checks can handle arbitrary complex aliasing situations, and therefore one
could ask why we even need the aliasing restrictions discussed above. The reason for these
restrictions is that we want to detect as many problems at compile time as possible,
and aliasing prevents that. Runtime checks are a kludge, and we would like to eliminate them
as much as we can. Rust avoids the aliasing problem by enforcing that there can only be
one reference to an object at any point in time if the object is currently mutable.
But that rule is too restrictive for typical C++ programs. Thus, we accept aliasing to
some degree. Ideally, the compiler sees all aliases, which allows for detecting
dependency (and content dependency) violations at compile time. If we cannot guarantee that,
the runtime checks handle the remaining cases.</p>
   <h2 class="heading settled" data-level="6" id="multithreading"><span class="secno">6. </span><span class="content">Multi Threading</span><a class="self-link" href="#multithreading"></a></h2>
   <p>Even though this paper concentrates on temporal memory safety in the single threaded case,
we ultimately need a solution for multi-thread memory safety, too. The only objects that
are safe to share between threads are const objects, atomics, objects that are explicitly marked
as thread-safe and that guarantee correctness themselves, and compounds of the former categories.
To simplify building thread-safe objects, the standard library should probably provide something
like a <code class="highlight"><c- n>locked</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-></code> wrapper that combines the <code class="highlight"><c- n>T</c-></code> with a mutex and that only allows access to
the underlying object via a callback mechanism:</p>
<pre class="highlight"><c- n>locked</c-><c- o>&lt;</c-><c- n>vector</c-><c- o>&lt;</c-><c- b>int</c-><c- o>>></c-> <c- n>foo</c-><c- p>;</c->
<c- p>...</c->
<c- n>foo</c-><c- p>.</c-><c- n>apply</c-><c- p>([](</c-><c- n>vector</c-><c- o>&lt;</c-><c- b>int</c-><c- o>>&amp;</c-> <c- n>c</c-><c- p>)</c-> <c- p>{</c->
   <c- c1>// This is implicitly protected by a mutex</c->
   <c- n>c</c-><c- p>.</c-><c- n>push_back</c-><c- p>(</c-><c- mi>1</c-><c- p>);</c->
   <c- c1>// The reference to c must not be captured</c->
<c- p>});</c->
</pre>
   <p>When we disallow capturing the pointer to the protected object (which we can, by forbidding capturing
dependencies on the object), we can make sure that the object will only be accessed under the mutex,
guaranteeing thread safety for that object.
When creating a new thread we must make sure that only thread-safe objects can be passed by reference
to the next thread.</p>
   <p>One problem we still have with that approach is that global objects are implicitly shared between threads.
Insisting that all global objects are thread-safe is impractical, in particular it would make simple programs
that rely upon global state for simplicity much more complex. It seems more promising to do something similar
to what the programming language <code class="highlight"><c- n>D</c-></code> does, where globals are thread-local by default. Making all non-constants
globals implicitly thread-local, and insisting on the thread-safety properties mentioned above for objects
that are marked as shared might be one way to introduce thread safety in C++.</p>
   <h2 class="heading settled" data-level="7" id="openquestions"><span class="secno">7. </span><span class="content">Open Questions</span><a class="self-link" href="#openquestions"></a></h2>
   <p>The approach sketched above guarantees temporal memory safety by keeping track of dependencies between objects,
both concerning the existence of objects and the content of objects, and by enforcing that an object
is no longer used after its dependencies became invalidated. Syntax questions aside, there are still some open
questions concerning this approach. In particular the balance between compile time checks and runtime checks
is important. Clearly, we want to detect as many problems as we can at compile time. And conversely, we
want to eliminate runtime checks as far as we can. It should be possible to eliminate some checks when,
e.g., we can prove that a reference never escapes and no alias is constructed and thus no dependency violation
can occur. But it is not clear yet how to best identify these situations. And perhaps some additional annotations
could help the compiler to better reason about safety.</p>
   <p>Furthermore, we need to combine temporal memory safety with spatial memory safety. The proof-of-concept
implementation in <a data-link-type="biblio" href="#biblio-ms" title="Memory Safety Checks">[ms]</a> provides a string implementation that offers both temporal and spatial memory
safety in its iterators, but it introduces a bounds check at every iterator dereference. In theory that
is not always necessary. For example the following code is guaranteed to be safe:</p>
<pre class="highlight"><c- n>string</c-> <c- n>foo</c-><c- p>;</c->
<c- k>for</c-> <c- p>(</c-><c- b>char</c-> <c- n>c</c-><c- o>:</c-><c- n>foo</c-><c- p>)</c-> <c- p>{</c->
   <c- p>...</c->
<c- p>}</c->
</pre>
   <p>The dependency rules make sure that the iterators used by the for loop stay valid, thus we do not need
any bounds checks. Manual iterator operations however could very well go beyond the <code class="highlight"><c- n>end</c-><c- p>()</c-></code> iterator and
thus need bounds checks. Can we somehow differentiate these cases at compile time?</p>
   <p>And finally we require a better solution for global objects. The multi-threading problems were already
discussed above, but the undefined initialization order is not acceptable either. When a global object <code class="highlight"><c- n>A</c-></code> depends on a global object <code class="highlight"><c- n>B</c-></code>, <code class="highlight"><c- n>B</c-></code> must be initialized before <code class="highlight"><c- n>A</c-></code>. Currently there is no universal
mechanism to guarantee that, let alone a fully automatic mechanism provided by the compiler. This has
to be addressed, too, to reach full memory safety.</p>
  </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-ms">[MS]
   <dd>Thomas Neumann. <a href="https://github.com/neumannt/memorysafety"><cite>Memory Safety Checks</cite></a>. URL: <a href="https://github.com/neumannt/memorysafety">https://github.com/neumannt/memorysafety</a>
  </dl>