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

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

	body {
		counter-reset: example figure issue;

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

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

		/* Colors */
		color: black;
		background: white top left fixed no-repeat;
		background-size: 25px auto;
	}


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	h1, h2, h3 {
		color: #005A9C;
		background: transparent;
	}

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

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

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

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

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

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

	p {
		margin: 1em 0;
	}

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

	pre, code, samp {
		font-family: Menlo, Consolas, "DejaVu Sans Mono", Monaco, monospace;
		font-size: .9em;
		page-break-inside: avoid;
		hyphens: none;
		text-transform: none;
	}
	pre code,
	code code {
		font-size: 100%;
	}

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

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

  /* Do something nice. */

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

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

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

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

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

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

	img {
		border-style: none;
	}

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

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

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

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

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

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

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

	blockquote {
		border-color: silver;
	}

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

	.issue {
		border-color: #E05252;
		background: #FBE9E9;
		counter-increment: issue;
		overflow: auto;
	}
	.issue::before, .issue > .marker {
		text-transform: uppercase;
		color: #AE1E1E;
		padding-right: 1em;
		text-transform: uppercase;
	}
	/* Add .issue::before { content: "Issue " counter(issue) " "; } for autogen numbers,
	   or use class="marker" to mark up the issue number in source. */

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

	.example {
		border-color: #E0CB52;
		background: #FCFAEE;
		counter-increment: example;
		overflow: auto;
		clear: both;
	}
	.example::before, .example > .marker {
		text-transform: uppercase;
		color: #827017;
		min-width: 7.5em;
		display: block;
	}
	/* Add .example::before { content: "Example " counter(example) " "; } for autogen numbers,
	   or use class="marker" to mark up the example number in source. */

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

	.note {
		border-color: #52E052;
		background: #E9FBE9;
		overflow: auto;
	}

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

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

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

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

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

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

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

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

	.annoying-warning:not(details),
	details.annoying-warning:not([open]) > summary,
	details.annoying-warning[open] {
		background: #fdd;
		color: red;
		font-weight: bold;
		padding: .75em 1em;
		border: thick red;
		border-style: solid;
		border-radius: 1em;
	}
	.annoying-warning :last-child {
		margin-bottom: 0;
	}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


/*
Alternate table alignment rules

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

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

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

Possible extra rowspan handling

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

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

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


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

	.toc a {
		/* More spacing; use padding to make it part of the click target. */
		padding-top: 0.1rem;
		/* Larger, more consistently-sized click target */
		display: block;
		/* Reverse color scheme */
		color: black;
		border-color: #3980B5;
		border-bottom-width: 3px !important;
		margin-bottom: 0px !important;
	}
	.toc a:visited {
		border-color: #054572;
	}
	.toc a:not(:focus):not(:hover) {
		/* Allow colors to cascade through from link styling */
		border-bottom-color: transparent;
	}

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

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

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

		/* Section numbers in a column of their own */
		.toc .secno {
			float: left;
			width: 4rem;
			white-space: nowrap;
		}

		.toc li {
			clear: both;
		}

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

		/* Tighten up indentation in narrow ToCs */
		@media (max-width: 30em) {
			:not(li) > .toc              { margin-left:  4rem; }
			.toc .secno                  { margin-left: -4rem; }
			.toc > li li li              { margin-left:  1rem; }
			.toc > li li li .secno       { margin-left: -5rem; }
			.toc > li li li li .secno    { margin-left: -6rem; }
			.toc > li li li li li .secno { margin-left: -7rem; }
		}
	/* } */

	@supports (display:grid) 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 {
			background: rgba(75%, 75%, 75%, .25);
			border-bottom: 3px solid #054572;
			margin-bottom: -3px;
		}
		#toc li li li .content {
			margin-left: 1rem;
		}
		#toc li li li li .content {
			margin-left: 2rem;
		}
	}


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

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

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

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

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

	table.index tr:hover td:not([rowspan]),
	table.index tr:hover th:not([rowspan]) {
		background: #f7f8f9;
	}

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

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

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

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

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



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

	.figure .caption, .sidefigure .caption, figcaption {
		/* in case figure is overlarge, limit caption to 50em */
		max-width: 50rem;
		margin-left: auto;
		margin-right: auto;
	}
	.overlarge > table {
		/* limit preferred width of table */
		max-width: 50em;
		margin-left: auto;
		margin-right: auto;
	}

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

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

    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 b76a1f3caa65320a39ee72dbf2680ea887ace619" name="generator">
  <link href="http://wg21.link/p0593r5" rel="canonical">
  <link href="https://isocpp.org/favicon.ico" rel="icon">
<style>/* style-md-lists */

/* This is a weird hack for me not yet following the commonmark spec
   regarding paragraph and lists. */
[data-md] > :first-child {
    margin-top: 0;
}
[data-md] > :last-child {
    margin-bottom: 0;
}</style>
<style>/* style-counters */

body {
    counter-reset: example figure issue;
}
.issue {
    counter-increment: issue;
}
.issue:not(.no-marker)::before {
    content: "Issue " counter(issue);
}

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

figcaption {
    counter-increment: figure;
}
figcaption:not(.no-marker)::before {
    content: "Figure " counter(figure) " ";
}</style>
<style>/* style-syntax-highlighting */

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

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

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

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

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

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

[data-link-type=biblio] {
    white-space: pre;
}</style>
 <body class="h-entry">
  <div class="head">
   <p data-fill-with="logo"></p>
   <h1 class="p-name no-ref" id="title">P0593R5<br>Implicit creation of objects for low-level object manipulation</h1>
   <h2 class="no-num no-toc no-ref heading settled" id="subtitle"><span class="content">Published Proposal, <time class="dt-updated" datetime="2019-10-06">2019-10-06</time></span></h2>
   <div data-fill-with="spec-metadata">
    <dl>
     <dt>This version:
     <dd><a class="u-url" href="http://wg21.link/p0593r5">http://wg21.link/p0593r5</a>
     <dt>Author:
     <dd>
      <dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:richard@metafoo.co.uk">Richard Smith</a> (<span class="p-org org">Google</span>)
     <dt>Former Author:
     <dd>
      <dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:ville.voutilainen@gmail.com">Ville Voutilainen</a>
     <dt>Audience:
     <dd>EWG, LWG, CWG
     <dt>Project:
     <dd>ISO/IEC JTC1/SC22/WG21 14882: Programming Language — C++
    </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>This paper proposes that objects of sufficiently trivial types be created on-demand as necessary within newly-allocated storage to give programs defined behavior.</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="#change-history"><span class="secno">1</span> <span class="content">Change history</span></a>
    <li>
     <a href="#motivating-examples"><span class="secno">2</span> <span class="content">Motivating examples</span></a>
     <ol class="toc">
      <li><a href="#idiomatic-c-code-as-c"><span class="secno">2.1</span> <span class="content">Idiomatic C code as C++</span></a>
      <li><a href="#objects-provided-as-byte-representation"><span class="secno">2.2</span> <span class="content">Objects provided as byte representation</span></a>
      <li><a href="#dynamic-construction-of-arrays"><span class="secno">2.3</span> <span class="content">Dynamic construction of arrays</span></a>
     </ol>
    <li>
     <a href="#approach"><span class="secno">3</span> <span class="content">Approach</span></a>
     <ol class="toc">
      <li><a href="#affected-types"><span class="secno">3.1</span> <span class="content">Affected types</span></a>
      <li><a href="#when-to-create-objects"><span class="secno">3.2</span> <span class="content">When to create objects</span></a>
      <li><a href="#type-punning"><span class="secno">3.3</span> <span class="content">Type punning</span></a>
      <li><a href="#union-copies"><span class="secno">3.4</span> <span class="content">Union copies</span></a>
      <li><a href="#constant-expressions"><span class="secno">3.5</span> <span class="content">Constant expressions</span></a>
      <li><a href="#pseudo-destructor-calls"><span class="secno">3.6</span> <span class="content">Pseudo-destructor calls</span></a>
      <li><a href="#practical-examples"><span class="secno">3.7</span> <span class="content">Practical examples</span></a>
      <li><a href="#direct-object-creation"><span class="secno">3.8</span> <span class="content">Direct object creation</span></a>
     </ol>
    <li><a href="#disposition-and-shipping-vehicle"><span class="secno">4</span> <span class="content">Disposition and shipping vehicle</span></a>
    <li>
     <a href="#wording"><span class="secno">5</span> <span class="content">Wording</span></a>
     <ol class="toc">
      <li><a href="#662-object-model-introobject"><span class="secno">5.1</span> <span class="content">6.6.2 Object model [intro.object]</span></a>
      <li><a href="#663-object-and-reference-lifetime-basiclife"><span class="secno">5.2</span> <span class="content">6.6.3 Object and reference lifetime [basic.life]</span></a>
      <li><a href="#67-types-basictypes"><span class="secno">5.3</span> <span class="content">6.7 Types [basic.types]</span></a>
      <li><a href="#7543-destruction-exprprimiddtor"><span class="secno">5.4</span> <span class="content">7.5.4.3 Destruction [expr.prim.id.dtor]</span></a>
      <li><a href="#7612-function-call-exprcall"><span class="secno">5.5</span> <span class="content">7.6.1.2 Function call [expr.call]</span></a>
      <li><a href="#101-properties-of-classes-classprop"><span class="secno">5.6</span> <span class="content">10.1 Properties of classes [class.prop]</span></a>
      <li><a href="#11342-copy-move-constructors-classcopyctor"><span class="secno">5.7</span> <span class="content">11.3.4.2 Copy/move constructors [class.copy.ctor]</span></a>
      <li><a href="#1135-copy-move-assignment-operator-classcopyassign"><span class="secno">5.8</span> <span class="content">11.3.5 Copy/move assignment operator [class.copy.assign]</span></a>
      <li><a href="#191092-static-member-functions-allocatortraitsmembers"><span class="secno">5.9</span> <span class="content">19.10.9.2 Static member functions [allocator.traits.members]</span></a>
      <li><a href="#191012-c-library-memory-allocation-cmalloc"><span class="secno">5.10</span> <span class="content">19.10.12 C library memory allocation [c.malloc]</span></a>
      <li><a href="#2053-header-cstring-synopsis-cstringsyn"><span class="secno">5.11</span> <span class="content">20.5.3 Header <code class="highlight"><c- o>&lt;</c-><c- n>cstring</c-><c- o>></c-></code> synopsis [cstring.syn]</span></a>
      <li><a href="#20102-header-memory-synopsis-memorysyn"><span class="secno">5.12</span> <span class="content">20.10.2 Header <code class="highlight"><c- o>&lt;</c-><c- n>memory</c-><c- o>></c-></code> synopsis [memory.syn]</span></a>
      <li><a href="#2010x-explicit-lifetime-management-objlifetime"><span class="secno">5.13</span> <span class="content">20.10.x <ins>Explicit lifetime management</ins> [obj.lifetime]</span></a>
      <li><a href="#2653-function-template-bit_cast-bitcast"><span class="secno">5.14</span> <span class="content">26.5.3 Function template <code class="highlight"><c- n>bit_cast</c-></code> [bit.cast]</span></a>
      <li><a href="#c5-c-and-iso-c-2017-diffcpp17"><span class="secno">5.15</span> <span class="content">C.5 C++ and ISO C++ 2017 [diff.cpp17]</span></a>
      <li><a href="#feature-test-macro"><span class="secno">5.16</span> <span class="content">Feature test macro</span></a>
     </ol>
    <li><a href="#acknowledgments"><span class="secno">6</span> <span class="content">Acknowledgments</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>
   <p>This paper resolves CWG2325.</p>
   <h2 class="heading settled" data-level="1" id="change-history"><span class="secno">1. </span><span class="content">Change history</span><a class="self-link" href="#change-history"></a></h2>
   <p>Since <a data-link-type="biblio" href="#biblio-p0593r0">[P0593R0]</a>:</p>
   <ul>
    <li data-md>
     <p>Paper expanded from Ville’s original call for solutions to a description of
a proposed solution, based on SG12 discussion.</p>
   </ul>
   <p>Since <a data-link-type="biblio" href="#biblio-p0593r1">[P0593R1]</a>:</p>
   <p>Incorporated further SG12 feedback:</p>
   <ul>
    <li data-md>
     <p>An explicit syntactic marker is required to indicate that objects should be
created. Existing obvious markers, such as the use of <code class="highlight"><c- n>malloc</c-></code>, or simply
performing member access on a union, suffice.</p>
    <li data-md>
     <p>Expand set of implicit-lifetime types to require <em>either</em> a trivial default
constructor <em>or</em> a trivial copy/move constructor, rather than requiring both.</p>
     <ul>
      <li data-md>
       <p>Types with only a trivial default constructor may be suitable for
member-by-member construction via class member access, even if the copy
or move constructor is non-trivial.</p>
      <li data-md>
       <p>Types with only a trivial copy/move constructor may be suitable for
initialization by copying (for example) an on-disk representation into
memory, even if the default constructor is non-trivial.</p>
     </ul>
    <li data-md>
     <p>Define the C standard library <code class="highlight"><c- n>memcpy</c-></code> and <code class="highlight"><c- n>memmove</c-></code> functions as triggering
implicit object creation.</p>
    <li data-md>
     <p>Add description of suggested "typed" form of <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>bless</c-></code>.</p>
   </ul>
   <p>Since <a data-link-type="biblio" href="#biblio-p0593r2">[P0593R2]</a>:</p>
   <ul>
    <li data-md>
     <p>Removed union member access being sufficient to implicitly create objects
based on objections from an implementer.</p>
   </ul>
   <p>Since <a data-link-type="biblio" href="#biblio-p0593r3">[P0593R3]</a>:</p>
   <ul>
    <li data-md>
     <p>Incorporated EWG feedback:</p>
     <ul>
      <li data-md>
       <p>Aggregates are considered implicit-lifetime types</p>
      <li data-md>
       <p>Provide a typed version of <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>bless</c-></code></p>
     </ul>
    <li data-md>
     <p>Added wording.</p>
   </ul>
   <p>Since P0594R4:</p>
   <ul>
    <li data-md>
     <p>Incorporated LEWG feedback:</p>
     <ul>
      <li data-md>
       <p>Removed untyped version of <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>bless</c-><c- p>(</c-><c- n>p</c-><c- p>,</c-> <c- n>n</c-><c- p>)</c-></code>, favoring use of <code class="highlight"><c- k>new</c-> <c- p>(</c-><c- n>p</c-><c- p>)</c-> <c- n>std</c-><c- o>::</c-><c- n>byte</c-><c- p>[</c-><c- n>n</c-><c- p>]</c-></code> in its place.</p>
      <li data-md>
       <p>Renamed typed version of <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>bless</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-></code> to <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>start_lifetime_as</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-></code>.</p>
      <li data-md>
       <p>Add <code class="highlight"><c- k>volatile</c-></code> variant of typed version.</p>
     </ul>
    <li data-md>
     <p>Added <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>bit_cast</c-></code> as an operation that implicitly creates objects.</p>
    <li data-md>
     <p>Added section on trivial union copies and added wording to copy the subobject structure.</p>
    <li data-md>
     <p>Separated standard library extensions from DR-level language rules fix.</p>
   </ul>
   <h2 class="heading settled" data-level="2" id="motivating-examples"><span class="secno">2. </span><span class="content">Motivating examples</span><a class="self-link" href="#motivating-examples"></a></h2>
   <h3 class="heading settled" data-level="2.1" id="idiomatic-c-code-as-c"><span class="secno">2.1. </span><span class="content">Idiomatic C code as C++</span><a class="self-link" href="#idiomatic-c-code-as-c"></a></h3>
   <p>Consider the following natural C program:</p>
<pre class="highlight"><c- k>struct</c-> <c- n>X</c-> <c- p>{</c-> <c- b>int</c-> <c- n>a</c-><c- p>,</c-> <c- n>b</c-><c- p>;</c-> <c- p>};</c->
<c- n>X</c-> <c- o>*</c-><c- nf>make_x</c-><c- p>()</c-> <c- p>{</c->
  <c- n>X</c-> <c- o>*</c-><c- n>p</c-> <c- o>=</c-> <c- p>(</c-><c- n>X</c-><c- o>*</c-><c- p>)</c-><c- n>malloc</c-><c- p>(</c-><c- k>sizeof</c-><c- p>(</c-><c- k>struct</c-> <c- n>X</c-><c- p>));</c->
  <c- n>p</c-><c- o>-></c-><c- n>a</c-> <c- o>=</c-> <c- mi>1</c-><c- p>;</c->
  <c- n>p</c-><c- o>-></c-><c- n>b</c-> <c- o>=</c-> <c- mi>2</c-><c- p>;</c->
  <c- k>return</c-> <c- n>p</c-><c- p>;</c->
<c- p>}</c->
</pre>
   <p>When compiled with a C++ compiler, this code has undefined behavior, because <code class="highlight"><c- n>p</c-><c- o>-></c-><c- n>a</c-></code> attempts to write to an <code class="highlight"><c- b>int</c-></code> subobject of an <code class="highlight"><c- n>X</c-></code> object, and this
program never created either an <code class="highlight"><c- n>X</c-></code> object nor an <code class="highlight"><c- b>int</c-></code> subobject.</p>
   <p>Per [intro.object]p1,</p>
   <blockquote> An <em>object</em> is created by a definition, by a <em>new-expression</em>, when
implicitly changing the active member of a union, or when a temporary
object is created. </blockquote>
   <p>... and this program did none of these things.</p>
   <h3 class="heading settled" data-level="2.2" id="objects-provided-as-byte-representation"><span class="secno">2.2. </span><span class="content">Objects provided as byte representation</span><a class="self-link" href="#objects-provided-as-byte-representation"></a></h3>
   <p>Suppose a C++ program is given a sequence of bytes (perhaps from disk or from a
network), and it knows those bytes are a valid representation of type <code class="highlight"><c- n>T</c-></code>. How
can it efficiently obtain a <code class="highlight"><c- n>T</c-> <c- o>*</c-></code> that can be legitimately used to access the
object?</p>
   <p>Example: (many details omitted for brevity)</p>
<pre class="highlight"><c- b>void</c-> <c- nf>process</c-><c- p>(</c-><c- n>Stream</c-> <c- o>*</c-><c- n>stream</c-><c- p>)</c-> <c- p>{</c->
  <c- n>unique_ptr</c-><c- o>&lt;</c-><c- b>char</c-><c- p>[]</c-><c- o>></c-> <c- n>buffer</c-> <c- o>=</c-> <c- n>stream</c-><c- o>-></c-><c- n>read</c-><c- p>();</c->
  <c- k>if</c-> <c- p>(</c-><c- n>buffer</c-><c- p>[</c-><c- mi>0</c-><c- p>]</c-> <c- o>==</c-> <c- n>FOO</c-><c- p>)</c->
    <c- n>process_foo</c-><c- p>(</c-><c- k>reinterpret_cast</c-><c- o>&lt;</c-><c- n>Foo</c-><c- o>*></c-><c- p>(</c-><c- n>buffer</c-><c- p>.</c-><c- n>get</c-><c- p>()));</c-> <c- c1>// #1</c->
  <c- k>else</c->
    <c- n>process_bar</c-><c- p>(</c-><c- k>reinterpret_cast</c-><c- o>&lt;</c-><c- n>Bar</c-><c- o>*></c-><c- p>(</c-><c- n>buffer</c-><c- p>.</c-><c- n>get</c-><c- p>()));</c-> <c- c1>// #2</c->
<c- p>}</c->
</pre>
   <p>This code leads to undefined behavior today: within <code class="highlight"><c- n>Stream</c-><c- o>::</c-><c- n>read</c-></code>, no <code class="highlight"><c- n>Foo</c-></code> or <code class="highlight"><c- n>Bar</c-></code> object is created, and so any attempt to access a <code class="highlight"><c- n>Foo</c-></code> object through the <code class="highlight"><c- n>Foo</c-><c- o>*</c-></code> produced by the cast at #1 would result in undefined behavior.</p>
   <h3 class="heading settled" data-level="2.3" id="dynamic-construction-of-arrays"><span class="secno">2.3. </span><span class="content">Dynamic construction of arrays</span><a class="self-link" href="#dynamic-construction-of-arrays"></a></h3>
   <p>Consider this program that attempts to implement a type like <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>vector</c-></code> (with many details omitted for brevity):</p>
<pre class="highlight"><c- k>template</c-><c- o>&lt;</c-><c- k>typename</c-> <c- n>T</c-><c- o>></c-> <c- k>struct</c-> <c- n>Vec</c-> <c- p>{</c->
  <c- b>char</c-> <c- o>*</c-><c- n>buf</c-> <c- o>=</c-> <c- k>nullptr</c-><c- p>,</c-> <c- o>*</c-><c- n>buf_end_size</c-> <c- o>=</c-> <c- k>nullptr</c-><c- p>,</c-> <c- o>*</c-><c- n>buf_end_capacity</c-> <c- o>=</c-> <c- k>nullptr</c-><c- p>;</c->
  <c- b>void</c-> <c- nf>reserve</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- b>size_t</c-> <c- n>n</c-><c- p>)</c-> <c- p>{</c->
    <c- b>char</c-> <c- o>*</c-><c- n>newbuf</c-> <c- o>=</c-> <c- p>(</c-><c- b>char</c-><c- o>*</c-><c- p>)</c-><c- o>::</c-><c- k>operator</c-> <c- k>new</c-><c- p>(</c-><c- n>n</c-> <c- o>*</c-> <c- k>sizeof</c-><c- p>(</c-><c- n>T</c-><c- p>),</c-> <c- n>std</c-><c- o>::</c-><c- n>align_val_t</c-><c- p>(</c-><c- k>alignof</c-><c- p>(</c-><c- n>T</c-><c- p>)));</c->
    <c- n>std</c-><c- o>::</c-><c- n>uninitialized_copy</c-><c- p>(</c-><c- n>begin</c-><c- p>(),</c-> <c- n>end</c-><c- p>(),</c-> <c- p>(</c-><c- n>T</c-><c- o>*</c-><c- p>)</c-><c- n>newbuf</c-><c- p>);</c-> <c- c1>// #a</c->

    <c- o>::</c-><c- k>operator</c-> <c- k>delete</c-><c- p>(</c-><c- n>buf</c-><c- p>,</c-> <c- n>std</c-><c- o>::</c-><c- n>align_val_t</c-><c- p>(</c-><c- k>alignof</c-><c- p>(</c-><c- n>T</c-><c- p>)));</c->
    <c- n>buf_end_size</c-> <c- o>=</c-> <c- n>newbuf</c-> <c- o>+</c-> <c- k>sizeof</c-><c- p>(</c-><c- n>T</c-><c- p>)</c-> <c- o>*</c-> <c- n>size</c-><c- p>();</c-> <c- c1>// #b</c->
    <c- n>buf_end_capacity</c-> <c- o>=</c-> <c- n>newbuf</c-> <c- o>+</c-> <c- k>sizeof</c-><c- p>(</c-><c- n>T</c-><c- p>)</c-> <c- o>*</c-> <c- n>n</c-><c- p>;</c->  <c- c1>// #c</c->
    <c- n>buf</c-> <c- o>=</c-> <c- n>newbuf</c-><c- p>;</c->
  <c- p>}</c->
  <c- b>void</c-> <c- nf>push_back</c-><c- p>(</c-><c- n>T</c-> <c- n>t</c-><c- p>)</c-> <c- p>{</c->
    <c- k>if</c-> <c- p>(</c-><c- n>buf_end_size</c-> <c- o>==</c-> <c- n>buf_end_capacity</c-><c- p>)</c->
      <c- n>reserve</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>max</c-><c- o>&lt;</c-><c- n>std</c-><c- o>::</c-><c- b>size_t</c-><c- o>></c-><c- p>(</c-><c- n>size</c-><c- p>()</c-> <c- o>*</c-> <c- mi>2</c-><c- p>,</c-> <c- mi>1</c-><c- p>));</c->
    <c- k>new</c-> <c- p>(</c-><c- n>buf_end_size</c-><c- p>)</c-> <c- n>T</c-><c- p>(</c-><c- n>t</c-><c- p>);</c->
    <c- n>buf_end_size</c-> <c- o>+=</c-> <c- k>sizeof</c-><c- p>(</c-><c- n>T</c-><c- p>);</c-> <c- c1>// #d</c->
  <c- p>}</c->
  <c- n>T</c-> <c- o>*</c-><c- nf>begin</c-><c- p>()</c-> <c- p>{</c-> <c- k>return</c-> <c- p>(</c-><c- n>T</c-><c- o>*</c-><c- p>)</c-><c- n>buf</c-><c- p>;</c-> <c- p>}</c->
  <c- n>T</c-> <c- o>*</c-><c- nf>end</c-><c- p>()</c-> <c- p>{</c-> <c- k>return</c-> <c- p>(</c-><c- n>T</c-><c- o>*</c-><c- p>)</c-><c- n>buf_end_size</c-><c- p>;</c-> <c- p>}</c->
  <c- n>std</c-><c- o>::</c-><c- b>size_t</c-> <c- n>size</c-><c- p>()</c-> <c- p>{</c-> <c- k>return</c-> <c- n>end</c-><c- p>()</c-> <c- o>-</c-> <c- n>begin</c-><c- p>();</c-> <c- p>}</c-> <c- c1>// #e</c->
<c- p>};</c->
<c- b>int</c-> <c- nf>main</c-><c- p>()</c-> <c- p>{</c->
  <c- n>Vec</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-> <c- n>v</c-><c- p>;</c->
  <c- n>v</c-><c- p>.</c-><c- n>push_back</c-><c- p>(</c-><c- mi>1</c-><c- p>);</c->
  <c- n>v</c-><c- p>.</c-><c- n>push_back</c-><c- p>(</c-><c- mi>2</c-><c- p>);</c->
  <c- n>v</c-><c- p>.</c-><c- n>push_back</c-><c- p>(</c-><c- mi>3</c-><c- p>);</c->
  <c- k>for</c-> <c- p>(</c-><c- b>int</c-> <c- nl>n</c-> <c- p>:</c-> <c- n>v</c-><c- p>)</c-> <c- p>{</c-> <c- d>/*...*/</c-> <c- p>}</c-> <c- c1>// #f</c->
<c- p>}</c->
</pre>
   <p>In practice, this code works across a range of existing implementations, but
according to the C++ object model, undefined behavior occurs at points #a, #b,
#c, #d, and #e, because they attempt to perform pointer arithmetic on a region
of allocated storage that does not contain an array object.</p>
   <p>At locations #b, #c, and #d, the arithmetic is performed on a <code class="highlight"><c- b>char</c-><c- o>*</c-></code>, and at
locations #a, #e, and #f, the arithmetic is performed on a <code class="highlight"><c- n>T</c-><c- o>*</c-></code>. Ideally, a
solution to this problem would imbue both calculations with defined behavior.</p>
   <h2 class="heading settled" data-level="3" id="approach"><span class="secno">3. </span><span class="content">Approach</span><a class="self-link" href="#approach"></a></h2>
   <p>The above snippets have a common theme: they attempt to use objects that they
never created. Indeed, there is a family of types for which programmers assume
they do not need to explicitly create objects. We propose to identify these
types, and carefully carve out rules that remove the need to explicitly create
such objects, by instead creating them implicitly.</p>
   <h3 class="heading settled" data-level="3.1" id="affected-types"><span class="secno">3.1. </span><span class="content">Affected types</span><a class="self-link" href="#affected-types"></a></h3>
   <p>If we are going to create objects automatically, we need a bare minimum of the
following two properties for the type:</p>
   <p>1) <em>Creating an instance of the type runs no code.</em> For class types, having a
trivially default constructible type is often the right constraint. However, we
should also consider cases where initially creating an object is non-trivial,
but copying it (for instance, from an on-disk representation) is trivial.</p>
   <p>2) <em>Destroying an instance of the type runs no code.</em> If the type maintains
invariants, we should not be implicitly creating objects of that type.</p>
   <p>Note that we’re only interested in properties of the object itself here, not
of its subobjects. In particular, the above two properties always hold for
array types. While creating or destroying array elements might run code,
creating the array object (without its elements) does not. For similar reasons,
it also seems reasonable to permit implicit object creation for aggregate class
types even if the aggregate contains an element with a non-trivial destructor.</p>
   <p>This suggests that the largest set of types we could apply this to is:</p>
   <ul>
    <li data-md>
     <p>Scalar types</p>
    <li data-md>
     <p>Aggregate types (arrays with any element type, aggregate classes with any members)</p>
    <li data-md>
     <p>Class types with a trivial destructor and a trivial constructor (of any kind)</p>
   </ul>
   <p>(Put another way, we can apply this to all types other than function type,
reference type, <code class="highlight"><c- b>void</c-></code>, and class types where all constructors are non-trivial
or where the destructor is non-trivial.)</p>
   <p>We will call types that satisfy the above constraints <em>implicit-lifetime types</em>.</p>
   <h3 class="heading settled" data-level="3.2" id="when-to-create-objects"><span class="secno">3.2. </span><span class="content">When to create objects</span><a class="self-link" href="#when-to-create-objects"></a></h3>
   <p>In the above cases, it would be sufficient for <code class="highlight"><c- n>malloc</c-></code> / <code class="highlight"><c- o>::</c-><c- k>operator</c-> <c- k>new</c-></code> to implicitly create sufficient objects to make the examples work. Imagine
that <code class="highlight"><c- n>malloc</c-></code> could "look into the future" and see how its storage would be
used, and create the set of objects that the program would eventually need.
If we somehow specified that <code class="highlight"><c- n>malloc</c-></code> did this, the behavior of many C-style
use cases would be defined.</p>
   <p>On typical implementations, we can argue that this is not only natural, it is
in some sense the status quo. Because the compiler typically does not make
assumptions about what objects are created within the implementation of <code class="highlight"><c- n>malloc</c-></code>, and because object creation itself typically has no effect on the
physical machine, the compiler must generate code that would be correct if <code class="highlight"><c- n>malloc</c-></code> did create that correct set of objects.</p>
   <p>However, this is not always sufficient. An allocation from <code class="highlight"><c- n>malloc</c-></code> may be
sequentially used to store multiple different types, for instance by way
of a memory pool that recycles the same allocation for multiple objects of
the same size. It should be possible to grant such cases the same power to
implicitly create objects as is de facto granted to <code class="highlight"><c- n>malloc</c-></code>.</p>
   <p>We could specify that implicit object creation happens automatically at any
program point that relies on an object existing. This has a great deal of
appeal: no explicit program action is ever required to create objects, and it
directly describes a simple model where objects are not distinguished from the
storage they occupy (this model gives the same results as C’s "effective type"
model in most cases). However, it also removes much of the power of scalar
type-based alias analysis. The C committee has long been struggling with the
conflict between their desire to support TBAA and their version of this rule,
as exemplified by C’s DR 236 (<a data-link-type="biblio" href="#biblio-c236">[C236]</a>), which lists a "resolution" not
reflected by the standard wording and that undesirably grants special powers to
function call boundaries (this is one of at least four different and
incompatible rules the C committee has at one point or another taken as the
resolution to that defect).  The lack of a reasonable resolution to these
problems, despite them being known for nearly two decades, suggests that this
is not a good path forward.</p>
   <p>Therefore we propose the following rule:</p>
   <blockquote>
    <p>Some operations are described as implicitly creating objects within a
specified region of storage. The abstract machine creates objects of
implicit-lifetime types within those regions of storage as needed to give the program
defined behavior. For each operation that is specified as implicitly creating
objects, that operation implicitly creates zero or more objects in its
specified region of storage if doing so would give the program defined
behavior. If no such sets of objects would give the program defined behavior,
the behavior of the program is undefined.</p>
   </blockquote>
   <p>The coherence of the above rule hinges on a key observation: changing the
set of objects that are implicitly created can only change whether a particular
program execution has defined behavior, not what the behavior is.</p>
   <p>We propose that at minimum the following operations be specified as implicitly
creating objects:</p>
   <ul>
    <li data-md>
     <p>Creation of an array of <code class="highlight"><c- b>char</c-></code>, <code class="highlight"><c- b>unsigned</c-> <c- b>char</c-></code>, or <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>byte</c-></code> implicitly
creates objects within that array.</p>
    <li data-md>
     <p>A call to <code class="highlight"><c- n>malloc</c-></code>, <code class="highlight"><c- n>calloc</c-></code>, <code class="highlight"><c- n>realloc</c-></code>, or any function named <code class="highlight"><c- k>operator</c-> <c- k>new</c-></code> or <code class="highlight"><c- k>operator</c-> <c- k>new</c-><c- p>[]</c-></code> implicitly creates objects in its returned storage.</p>
    <li data-md>
     <p><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>allocator</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>::</c-><c- n>allocate</c-></code> likewise implicitly creates objects in its
returned storage; the allocator requirements should require other allocator
implementations to do the same.</p>
    <li data-md>
     <p>A call to <code class="highlight"><c- n>memmove</c-></code> behaves as if it</p>
     <ol>
      <li data-md>
       <p>copies the source storage to a temporary area</p>
      <li data-md>
       <p>implicitly creates objects in the destination storage, and then</p>
      <li data-md>
       <p>copies the temporary storage to the destination storage.</p>
     </ol>
     <p>This permits <code class="highlight"><c- n>memmove</c-></code> to preserve the types of trivially-copyable objects,
or to be used to reinterpret a byte representation of one object as that of
another object.</p>
    <li data-md>
     <p>A call to <code class="highlight"><c- n>memcpy</c-></code> behaves the same as a call to <code class="highlight"><c- n>memmove</c-></code> except that it
introduces an overlap restriction between the source and destination.</p>
    <li data-md>
     <p>A call to <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>bit_cast</c-></code> implicitly creates objects in the result, to
handle the case where the destination type contains a union.</p>
    <li data-md>
     <p>A new barrier operation (distinct from <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>launder</c-></code>, which does not create
objects) could be introduced to the standard library, with semantics
equivalent to a <code class="highlight"><c- n>memmove</c-></code> with the same source and destination storage.
Prior versions of this document suggested:</p>
<pre class="highlight">    <c- c1>// Requires: [start, (char*)start + length) denotes a region of allocated</c->
    <c- c1>// storage that is a subset of the region of storage reachable through start.</c->
    <c- c1>// Effects: implicitly creates objects within the denoted region.</c->
    <c- b>void</c-> <c- n>std</c-><c- o>::</c-><c- n>bless</c-><c- p>(</c-><c- b>void</c-> <c- o>*</c-><c- n>start</c-><c- p>,</c-> <c- b>size_t</c-> <c- n>length</c-><c- p>);</c->
</pre>
     <p>However, LEWG review observed that <code class="highlight"><c- k>new</c-> <c- p>(</c-><c- n>start</c-><c- p>)</c-> <c- n>std</c-><c- o>::</c-><c- n>byte</c-><c- p>[</c-><c- n>length</c-><c- p>]</c-></code> can be
used to obtain the desired effect by reusing the first rule above.</p>
   </ul>
   <p>In addition to the above, an implementation-defined set of non-standard memory
allocation and mapping functions, such as <code class="highlight"><c- n>mmap</c-></code> on POSIX systems and <code class="highlight"><c- n>VirtualAlloc</c-></code> on Windows systems, should be specified as implicitly creating
objects.</p>
   <p>Note that a pointer <code class="highlight"><c- k>reinterpret_cast</c-></code> is not considered sufficient to trigger
implicit object creation.</p>
   <h3 class="heading settled" data-level="3.3" id="type-punning"><span class="secno">3.3. </span><span class="content">Type punning</span><a class="self-link" href="#type-punning"></a></h3>
   <p>We do not wish examples such as the following to become valid:</p>
<pre class="highlight"><c- b>float</c-> <c- nf>do_bad_things</c-><c- p>(</c-><c- b>int</c-> <c- n>n</c-><c- p>)</c-> <c- p>{</c->
  <c- k>alignof</c-><c- p>(</c-><c- b>int</c-><c- p>)</c-> <c- k>alignof</c-><c- p>(</c-><c- b>float</c-><c- p>)</c->
    <c- b>char</c-> <c- n>buffer</c-><c- p>[</c-><c- n>max</c-><c- p>(</c-><c- k>sizeof</c-><c- p>(</c-><c- b>int</c-><c- p>),</c-> <c- k>sizeof</c-><c- p>(</c-><c- b>float</c-><c- p>))];</c->
  <c- o>*</c-><c- p>(</c-><c- b>int</c-><c- o>*</c-><c- p>)</c-><c- n>buffer</c-> <c- o>=</c-> <c- n>n</c-><c- p>;</c->      <c- c1>// #1</c->
  <c- k>new</c-> <c- p>(</c-><c- n>buffer</c-><c- p>)</c-> <c- n>std</c-><c- o>::</c-><c- n>byte</c-><c- p>[</c-><c- k>sizeof</c-><c- p>(</c-><c- n>buffer</c-><c- p>)];</c->
  <c- k>return</c-> <c- p>(</c-><c- o>*</c-><c- b>float</c-><c- o>*</c-><c- p>)</c-><c- n>buffer</c-><c- p>;</c-> <c- c1>// #2</c->
<c- p>}</c->
</pre>
<pre class="highlight"><c- b>float</c-> <c- nf>do_bad_things</c-><c- p>(</c-><c- b>int</c-> <c- n>n</c-><c- p>)</c-> <c- p>{</c->
  <c- k>union</c-> <c- p>{</c-> <c- b>int</c-> <c- n>n</c-><c- p>;</c-> <c- b>float</c-> <c- n>f</c-><c- p>;</c-> <c- p>}</c-> <c- n>u</c-><c- p>;</c->
  <c- n>u</c-><c- p>.</c-><c- n>n</c-> <c- o>=</c-> <c- n>n</c-><c- p>;</c->    <c- c1>// #1</c->
  <c- k>new</c-> <c- p>(</c-><c- o>&amp;</c-><c- n>u</c-><c- p>)</c-> <c- n>std</c-><c- o>::</c-><c- n>byte</c-><c- p>[</c-><c- k>sizeof</c-><c- p>(</c-><c- n>u</c-><c- p>)];</c->
  <c- k>return</c-> <c- n>u</c-><c- p>.</c-><c- n>f</c-><c- p>;</c-> <c- c1>// #2</c->
<c- p>}</c->
</pre>
   <p>The proposed rule would permit an <code class="highlight"><c- b>int</c-></code> object to spring into existence
to make line #1 valid (in each case), and would permit a <code class="highlight"><c- b>float</c-></code> object to
likewise spring into existence to make line #2 valid.</p>
   <p>However, these examples still do not have defined behavior under the
proposed rule. The reason is a consequence of [basic.life]p4:</p>
   <blockquote> The properties ascribed to objects and references throughout this document
apply for a given object or reference only during its lifetime. </blockquote>
   <p>Specifically, the value held by an object is only stable throughout its
lifetime. When the lifetime of the <code class="highlight"><c- b>int</c-></code> object in line #1 ends (when
its storage is reused by the <code class="highlight"><c- b>float</c-></code> object in line #2), its value is
gone. Symmetrically, when the <code class="highlight"><c- b>float</c-></code> object is created, the object has
an indeterminate value ([dcl.init]p12), and therefore any attempt to
load its value results in undefined behavior.</p>
   <p>Thus we retain the property (essential to modern scalar type-based
alias analysis) that loads of some scalar type can be considered to
not alias earlier stores of unrelated scalar types.</p>
   <h3 class="heading settled" data-level="3.4" id="union-copies"><span class="secno">3.4. </span><span class="content">Union copies</span><a class="self-link" href="#union-copies"></a></h3>
   <p>Consider an example such as:</p>
<pre class="highlight"><c- k>union</c-> <c- n>U</c-> <c- p>{</c->
  <c- b>int</c-> <c- n>n</c-><c- p>;</c->
  <c- b>float</c-> <c- n>f</c-><c- p>;</c->
<c- p>};</c->
<c- b>float</c-> <c- nf>pun</c-><c- p>(</c-><c- b>int</c-> <c- n>n</c-><c- p>)</c-> <c- p>{</c->
  <c- n>U</c-> <c- n>u</c-> <c- o>=</c-> <c- p>{.</c-><c- n>n</c-> <c- o>=</c-> <c- n>n</c-><c- p>};</c->
  <c- n>U</c-> <c- n>u2</c-> <c- o>=</c-> <c- n>u</c-><c- p>;</c->    <c- c1>// #1</c->
  <c- k>return</c-> <c- n>u2</c-><c- p>.</c-><c- n>f</c-><c- p>;</c-> <c- c1>// #2</c->
<c- p>}</c->
</pre>
   <p>In the current language rules,
a strict interpretation of the wording would suggest that
only the object representation of <code class="highlight"><c- n>u</c-></code> is copied on line #1,
but no union member’s lifetime begins, so <code class="highlight"><c- n>u2</c-></code> has no active union member.
This is clearly not the appropriate outcome.</p>
   <p>We could rectify this in one of two natural ways:</p>
   <ul>
    <li data-md>
     <p>Line #1 copies the object structure of <code class="highlight"><c- n>u</c-></code> to <code class="highlight"><c- n>u2</c-></code>, so that the active
member of <code class="highlight"><c- n>u2</c-></code> is <code class="highlight"><c- n>n</c-></code>;
line #2 does not have defined behavior, just as if it returned <code class="highlight"><c- n>u</c-><c- p>.</c-><c- n>f</c-></code>.</p>
    <li data-md>
     <p>Line #1 implicitly creates objects;
at line #2 we have implicitly bit-cast <code class="highlight"><c- n>n</c-></code> to <code class="highlight"><c- b>float</c-></code>.</p>
   </ul>
   <p>This paper proposes we adopt the former option,
as it preserves equational reasoning and results in more explicit code
(that is, using <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>bit_cast</c-></code> to perform bit-casts rather than union copies).</p>
   <h3 class="heading settled" data-level="3.5" id="constant-expressions"><span class="secno">3.5. </span><span class="content">Constant expressions</span><a class="self-link" href="#constant-expressions"></a></h3>
   <p>Constant expression evaluation is currently very conservative with regard to
object creation. There is a tension here: on the one hand, constant expression
evaluation gives us an opportunity to disallow runtime program semantics that
we consider undesirable or problematic, and on the other hand, users strongly
desire a full compile-time evaluation mechanism with the same semantics as the
base language.</p>
   <p>Following the existing conservatism in constant expression evaluation,
and specific concerns about high implementation costs in some existing implementations,
we propose that implicit creation of objects
should <em>not</em> be performed during such evaluation.
The disallowance of pointer or reference <code class="highlight"><c- k>reinterpret_cast</c-></code>s in constant expressions
is believed to make the lack of implicit object creation unobservable.</p>
   <h3 class="heading settled" data-level="3.6" id="pseudo-destructor-calls"><span class="secno">3.6. </span><span class="content">Pseudo-destructor calls</span><a class="self-link" href="#pseudo-destructor-calls"></a></h3>
   <p>In the current C++ language rules, "pseudo-destructor" calls may be used in
generic code to allow such code to be ambivalent as to whether an object is of
class type:</p>
<pre class="highlight"><c- k>template</c-><c- o>&lt;</c-><c- k>typename</c-> <c- n>T</c-><c- o>></c-> <c- b>void</c-> <c- n>destroy</c-><c- p>(</c-><c- n>T</c-> <c- o>*</c-><c- n>p</c-><c- p>)</c-> <c- p>{</c-> <c- n>p</c-><c- o>->~</c-><c- n>T</c-><c- p>();</c-> <c- p>}</c->
</pre>
   <p>When <code class="highlight"><c- n>T</c-></code> is, say, <code class="highlight"><c- b>int</c-></code>, the pseudo-destructor expression <code class="highlight"><c- n>p</c-><c- o>->~</c-><c- n>T</c-><c- p>()</c-></code> is specified
as having no effect. We believe this is an error: such an expression should have
a lifetime effect, ending the lifetime of the <code class="highlight"><c- b>int</c-></code> object. Likewise, calling a
destructor of a class object should always end the lifetime of that object,
regardless of whether the destructor is trivial.</p>
   <p>This change improves the ability of static and dynamic analysis tools to reason
about the lifetimes of C++ objects.</p>
   <h3 class="heading settled" data-level="3.7" id="practical-examples"><span class="secno">3.7. </span><span class="content">Practical examples</span><a class="self-link" href="#practical-examples"></a></h3>
<pre class="highlight"><c- n>std</c-><c- o>::</c-><c- n>vector</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-> <c- n>vi</c-><c- p>;</c->
<c- n>vi</c-><c- p>.</c-><c- n>reserve</c-><c- p>(</c-><c- mi>4</c-><c- p>);</c->
<c- n>vi</c-><c- p>.</c-><c- n>push_back</c-><c- p>(</c-><c- mi>1</c-><c- p>);</c->
<c- b>int</c-> <c- o>*</c-><c- n>p</c-> <c- o>=</c-> <c- o>&amp;</c-><c- n>vi</c-><c- p>.</c-><c- n>back</c-><c- p>();</c->
<c- n>vi</c-><c- p>.</c-><c- n>push_back</c-><c- p>(</c-><c- mi>2</c-><c- p>);</c->
<c- n>vi</c-><c- p>.</c-><c- n>push_back</c-><c- p>(</c-><c- mi>3</c-><c- p>);</c->
<c- b>int</c-> <c- n>n</c-> <c- o>=</c-> <c- o>*</c-><c- n>p</c-><c- p>;</c->
</pre>
   <p>Within the implementation of <code class="highlight"><c- n>vector</c-></code>, some storage is allocated to hold
an array of up to 4 <code class="highlight"><c- b>int</c-></code>s. Ignoring minor differences, there are two ways
to create implicit objects to give the execution of this program defined
behavior: within the allocated storage, either an <code class="highlight"><c- b>int</c-><c- p>[</c-><c- mi>3</c-><c- p>]</c-></code> object or an <code class="highlight"><c- b>int</c-><c- p>[</c-><c- mi>4</c-><c- p>]</c-></code> object is created. Both are correct interpretations of the program,
and naturally both result in the same behavior. We can choose to view the
program as being in the superposition of those two states. If we add a fourth <code class="highlight"><c- n>push_back</c-></code> call to the program prior to the initialization of <code class="highlight"><c- n>n</c-></code>, then only
the <code class="highlight"><c- b>int</c-><c- p>[</c-><c- mi>4</c-><c- p>]</c-></code> interpretation remains valid.</p>
<pre class="highlight"><c- n>unique_ptr</c-><c- o>&lt;</c-><c- b>char</c-><c- p>[]</c-><c- o>></c-> <c- n>Stream</c-><c- o>::</c-><c- n>read</c-><c- p>()</c-> <c- p>{</c->
  <c- c1>// ... determine data size ...</c->
  <c- n>unique_ptr</c-><c- o>&lt;</c-><c- b>char</c-><c- p>[]</c-><c- o>></c-> <c- n>buffer</c-><c- p>(</c-><c- k>new</c-> <c- b>char</c-><c- p>[</c-><c- n>N</c-><c- p>]);</c->
  <c- c1>// ... copy data into buffer ...</c->
  <c- k>return</c-> <c- n>buffer</c-><c- p>;</c->
<c- p>}</c->

<c- b>void</c-> <c- n>process</c-><c- p>(</c-><c- n>Stream</c-> <c- o>*</c-><c- n>stream</c-><c- p>)</c-> <c- p>{</c->
  <c- n>unique_ptr</c-><c- o>&lt;</c-><c- b>char</c-><c- p>[]</c-><c- o>></c-> <c- n>buffer</c-> <c- o>=</c-> <c- n>stream</c-><c- o>-></c-><c- n>read</c-><c- p>();</c->
  <c- k>if</c-> <c- p>(</c-><c- n>buffer</c-><c- p>[</c-><c- mi>0</c-><c- p>]</c-> <c- o>==</c-> <c- n>FOO</c-><c- p>)</c->
    <c- n>process_foo</c-><c- p>(</c-><c- k>reinterpret_cast</c-><c- o>&lt;</c-><c- n>Foo</c-><c- o>*></c-><c- p>(</c-><c- n>buffer</c-><c- p>.</c-><c- n>get</c-><c- p>()));</c-> <c- c1>// #1</c->
  <c- k>else</c->
    <c- nf>process_bar</c-><c- p>(</c-><c- k>reinterpret_cast</c-><c- o>&lt;</c-><c- n>Bar</c-><c- o>*></c-><c- p>(</c-><c- n>buffer</c-><c- p>.</c-><c- n>get</c-><c- p>()));</c-> <c- c1>// #2</c->
<c- p>}</c->
</pre>
   <p>Note the <code class="highlight"><c- k>new</c-> <c- b>char</c-><c- p>[</c-><c- n>N</c-><c- p>]</c-></code> implicitly creates objects within the allocated array.
In this case, the program would have defined behavior if an object of type <code class="highlight"><c- n>Foo</c-></code> or <code class="highlight"><c- n>Bar</c-></code> (as appropriate for the content of the incoming data) were
implicitly created <em>prior</em> to <code class="highlight"><c- n>Stream</c-><c- o>::</c-><c- n>read</c-></code> populating its buffer. Therefore,
regardless of which arm of the <code class="highlight"><c- k>if</c-></code> is taken, there is a set of implicit
objects sufficient to give the program defined behavior, and thus the behavior
of the program is defined.</p>
   <h3 class="heading settled" data-level="3.8" id="direct-object-creation"><span class="secno">3.8. </span><span class="content">Direct object creation</span><a class="self-link" href="#direct-object-creation"></a></h3>
   <p>In some cases it is desirable to change the dynamic type of existing storage
while maintaining the object representation. If the destination type is a
trivially-copyable implicit-lifetime type, this can be accomplished by copying
the storage elsewhere, using placement new of an array of byte-like type, and
copying the storage back to its original location, then using <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>launder</c-></code> to
acquire a pointer to the newly-created object. However, for expressivity and
optimizability, a combined operation to create an object of implicit-lifetime
type in-place while preserving the object representation may be useful. For
this we propose:</p>
<pre class="highlight"><c- c1>// Effects: create an object of implicit-lifetype type T in the storage</c->
<c- c1>//          pointed to by T, while preserving the object representation.</c->
<c- k>template</c-><c- o>&lt;</c-><c- k>typename</c-> <c- n>T</c-><c- o>></c-> <c- n>T</c-> <c- o>*</c-><c- n>start_lifetime_as</c-><c- p>(</c-><c- b>void</c-> <c- o>*</c-><c- n>p</c-><c- p>);</c->
</pre>
   <p>Note that such an operation is not sufficient to implement <i><code class="highlight"><c- n>node_handle</c-></code></i> (<a data-link-type="biblio" href="#biblio-p0083r3">[P0083R3]</a>) for map-like containers. <i><code class="highlight"><c- n>node_handle</c-></code></i> requires the
ability to take a <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>pair</c-><c- o>&lt;</c-><c- k>const</c-> <c- n>Key</c-><c- p>,</c-> <c- n>Value</c-><c- o>></c-></code> and permit mutation of the <code class="highlight"><c- n>Key</c-></code> portion (without destroying and recreating the <code class="highlight"><c- n>Key</c-></code> object), even when <code class="highlight"><c- n>Key</c-></code> is not an implicit-lifetime type, so the above operation does not
quite suffice. However, we could imagine extending its semantics to also permit
conversions where each subobject of non-implicit-lifetime type in the
destination corresponds to an object of the same type (ignoring
cv-qualifications) in the source.</p>
   <h2 class="heading settled" data-level="4" id="disposition-and-shipping-vehicle"><span class="secno">4. </span><span class="content">Disposition and shipping vehicle</span><a class="self-link" href="#disposition-and-shipping-vehicle"></a></h2>
   <p>This paper did not complete LWG review in time for C++20. However, the
functionality contained herein can be split into two portions:</p>
   <ul>
    <li data-md>
     <p>The core language change that gives defined behavior to various constructs
that have historically been assumed to work, and</p>
    <li data-md>
     <p>The standard library addition of <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>start_lifetime_as</c-></code>, which is a pure
extension.</p>
   </ul>
   <p>The author suggests that the committee considers adopting the former portion of
this paper as a Defect Report, for possible inclusion into the C++20 IS, and
that the latter portion be deferred to C++23.</p>
   <p>Wording is presented assuming the committee agrees with this direction.</p>
   <div class="advisement">
     The portions of the wording below corresponding to the library extension
are presented in this style, and marked <b>"Library extension,
not for inclusion in C++20"</b>. 
    <p>Such wording is presented only for context and should not be applied to the
C++20 working draft.</p>
   </div>
   <h2 class="heading settled" data-level="5" id="wording"><span class="secno">5. </span><span class="content">Wording</span><a class="self-link" href="#wording"></a></h2>
   <h3 class="heading settled" data-level="5.1" id="662-object-model-introobject"><span class="secno">5.1. </span><span class="content">6.6.2 Object model [intro.object]</span><a class="self-link" href="#662-object-model-introobject"></a></h3>
   <p>Change in 6.6.2 [intro.object] paragraph 1:</p>
   <blockquote>
    <p>
     The constructs in a C++ program
create, destroy, refer to, access, and manipulate objects.
An <i>object</i> is created
by a definition (6.1),
by a new-expression (7.6.2.4), 
     <ins>by
an operation that implicitly creates objects (see below),</ins>
      when implicitly changing the active member of a union (10.4), or
when a temporary object is created (7.3.4, 6.6.7). [...]
    </p>
   </blockquote>
   <p>Add a new paragraph at the end of [intro.object]:</p>
   <blockquote>
    <ins>Some operations are described as <i>implicitly creating objects</i> within a specified region of storage.
For each operation that is specified as implicitly creating objects,
that operation implicitly creates and starts the lifetime of zero or more objects
of implicit-lifetime types (6.7 [basic.types])
in its specified region of storage
if doing so would result in the program having defined behavior.
If no such sets of objects would give the program defined behavior,
the behavior of the program is undefined.
[<em>Note</em>: Such operations do not start the lifetimes of subobjects
of such objects that are not themselves of implicit-lifetime types. -<em>end note</em>]</ins>
   </blockquote>
   <p>Add an example following the new paragraph:</p>
   <blockquote>
    <ins>
     [ Example: 
<pre class="highlight" style="color: #000; background-color: #c8ffc8"><c- cp>#include</c-> <cstdlib>
struct X { int a, b; };
<c- n>X</c-> <c- o>*</c-><c- nf>make_x</c-><c- p>()</c-> <c- p>{</c->
  <c- c1>// The call to std::malloc implicitly creates an object of type X</c->
  <c- c1>// and its subobjects a and b in order to give the subsequent</c->
  <c- c1>// class member access operations defined behavior.</c->
  <c- n>X</c-> <c- o>*</c-><c- n>p</c-> <c- o>=</c-> <c- p>(</c-><c- n>X</c-><c- o>*</c-><c- p>)</c-><c- n>std</c-><c- o>::</c-><c- n>malloc</c-><c- p>(</c-><c- k>sizeof</c-><c- p>(</c-><c- k>struct</c-> <c- n>X</c-><c- p>));</c->
  <c- n>p</c-><c- o>-></c-><c- n>a</c-> <c- o>=</c-> <c- mi>1</c-><c- p>;</c->
  <c- n>p</c-><c- o>-></c-><c- n>b</c-> <c- o>=</c-> <c- mi>2</c-><c- p>;</c->
  <c- k>return</c-> <c- n>p</c-><c- p>;</c->
<c- p>}</c->
</cstdlib></pre>
      -- end example ]
    </ins>
   </blockquote>
   <p>Add another paragraph:</p>
   <blockquote>
    <ins>An operation that begins the lifetime of an array of <code class="highlight"><c- b>char</c-></code>, <code class="highlight"><c- b>unsigned</c-> <c- b>char</c-></code>, or <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>byte</c-></code> implicitly creates objects
within the region of storage occupied by the array.
[ Note: the array object provides storage for these objects. -- end note ]
Any implicit or explicit invocation of
a function named <code class="highlight"><c- k>operator</c-> <c- k>new</c-></code> or <code class="highlight"><c- k>operator</c-> <c- k>new</c-><c- p>[]</c-></code> implicitly creates objects in the returned region of storage.
Some functions in the C++ standard library implicitly create objects
(19.10.9.2 [allocator.traits.members],
19.10.12 [c.malloc], 20.5.3 [cstring.syn], 26.5.3 [bit.cast]). </ins>
   </blockquote>
   <div class="advisement">
     <b>Library extension, not for inclusion in C++20.</b> 
    <p>Change in the newly-added paragraph:</p>
    <blockquote>
     <p>
      Some functions in the C++ standard library implicitly create objects
(
      <ins>16.6.x [obj.lifetime],</ins>
       19.10.9.2 [allocator.traits.members],
19.10.12 [c.malloc], 20.5.3 [cstring.syn], 26.5.3 [bit.cast]).
     </p>
    </blockquote>
   </div>
   <h3 class="heading settled" data-level="5.2" id="663-object-and-reference-lifetime-basiclife"><span class="secno">5.2. </span><span class="content">6.6.3 Object and reference lifetime [basic.life]</span><a class="self-link" href="#663-object-and-reference-lifetime-basiclife"></a></h3>
   <p>Change in 6.6.3 [basic.life] paragraph 1:</p>
   <blockquote>
    <p>
     [...] The lifetime of an object of type T begins when:
[...]
except that if the object is a union member or subobject thereof,
its lifetime only begins if
that union member is the initialized member in the union (9.3.1, 11.9.2),
or as described in 11.4 
     <ins>and [class.copy.ctor]</ins>
     .
[...] The lifetime of an object <code class="highlight"><c- n>o</c-></code> of type <code class="highlight"><c- n>T</c-></code> ends when:
    </p>
    <ul>
     <li data-md>
      <p>if <code class="highlight"><c- n>T</c-></code> is a non-class type, the object is destroyed, or</p>
     <li data-md>
      <p>if <code class="highlight"><c- n>T</c-></code> is a class type, the destructor call starts, or</p>
     <li data-md>
      <p>the storage which the object occupies is released, or
is reused by an object that is not nested within <code class="highlight"><c- n>o</c-></code> (6.6.2).</p>
    </ul>
   </blockquote>
   <h3 class="heading settled" data-level="5.3" id="67-types-basictypes"><span class="secno">5.3. </span><span class="content">6.7 Types [basic.types]</span><a class="self-link" href="#67-types-basictypes"></a></h3>
   <p>Change in 6.7 [basic.types] paragraph 9:</p>
   <blockquote>
    <p>
     [...] Scalar types, trivial class types (10.1), arrays of such types and cv-qualified versions of these types are collectively called <i>trivial types</i>.
Scalar types, standard-layout class types (10.1), arrays of such types and cv-qualified versions of these types are collectively called <i>standard-layout types</i>. 
     <ins> Scalar types, implicit-lifetime class types ([class.prop]), array types, and cv-qualified versions of these types are collectively called <i>implicit-lifetime types</i>.</ins>
    </p>
   </blockquote>
   <h3 class="heading settled" data-level="5.4" id="7543-destruction-exprprimiddtor"><span class="secno">5.4. </span><span class="content">7.5.4.3 Destruction [expr.prim.id.dtor]</span><a class="self-link" href="#7543-destruction-exprprimiddtor"></a></h3>
   <p>Change in 7.5.4.3 [expr.prim.id.dtor] paragraph 2:</p>
   <blockquote>
    <p>
     If the <em>id-expression</em> names a pseudo-destructor, <code class="highlight"><c- n>T</c-></code> shall be a scalar type and
the <em>id-expression</em> shall appear as the right operand of a class member access (7.6.1.4)
that forms the <em>postfix-expression</em> of a function call (7.6.1.2).
[Note: Such a call 
     <del>has no effect</del>
     <ins>ends the lifetime
of the object ([expr.call], [basic.life])</ins>
     . —end note]
    </p>
   </blockquote>
   <h3 class="heading settled" data-level="5.5" id="7612-function-call-exprcall"><span class="secno">5.5. </span><span class="content">7.6.1.2 Function call [expr.call]</span><a class="self-link" href="#7612-function-call-exprcall"></a></h3>
   <p>Change in 7.6.1.2 [expr.call] paragraph 5:</p>
   <blockquote>
    <p>
     [...] If the <em>postfix-expression</em> names a <em>pseudo-destructor</em>, 
     <ins>the <em>postfix-expression</em> must be a possibly-parenthesized
class member access (7.6.1.4), and</ins>
      the function call 
     <del>has no effect</del>
     <ins>destroys
the object of scalar type denoted by the object expression of
the class member access</ins>
      .
    </p>
   </blockquote>
   <h3 class="heading settled" data-level="5.6" id="101-properties-of-classes-classprop"><span class="secno">5.6. </span><span class="content">10.1 Properties of classes [class.prop]</span><a class="self-link" href="#101-properties-of-classes-classprop"></a></h3>
   <p>Add a new paragraph at the end of [class.prop]:</p>
   <blockquote>
    <ins>A class <code class="highlight"><c- n>S</c-></code> is an <i>implicit-lifetime class</i> if it
is an aggregate ([dcl.aggr]) or has
at least one trivial eligible constructor and
a trivial, non-deleted destructor.</ins>
   </blockquote>
   <h3 class="heading settled" data-level="5.7" id="11342-copy-move-constructors-classcopyctor"><span class="secno">5.7. </span><span class="content">11.3.4.2 Copy/move constructors [class.copy.ctor]</span><a class="self-link" href="#11342-copy-move-constructors-classcopyctor"></a></h3>
   <p>Change in 11.3.4.2 [class.copy.ctor] paragraph 15:</p>
   <blockquote>
    <p>The implicitly-defined copy/move constructor for a union <code class="highlight"><c- n>X</c-></code> copies the object representation (6.7) of <code class="highlight"><c- n>X</c-></code>.</p>
    <ins>For each object nested within ([intro.object])
the object that is the source of the copy,
a corresponding object <i>o</i> nested within the destination
is identified (if the object is a subobject) or created (otherwise),
and the lifetime of <i>o</i> begins before the copy is performed.</ins>
   </blockquote>
   <h3 class="heading settled" data-level="5.8" id="1135-copy-move-assignment-operator-classcopyassign"><span class="secno">5.8. </span><span class="content">11.3.5 Copy/move assignment operator [class.copy.assign]</span><a class="self-link" href="#1135-copy-move-assignment-operator-classcopyassign"></a></h3>
   <p>Change in 11.3.5 [class.copy.assign] paragraph 13:</p>
   <blockquote>
    <p>The implicitly-defined copy assignment operator for a union <code class="highlight"><c- n>X</c-></code> copies the object representation (6.7) of <code class="highlight"><c- n>X</c-></code>.</p>
    <ins>If the source and destination of the assignment are not the
same object, then
for each object nested within ([intro.object])
the object that is the source of the copy,
a corresponding object <i>o</i> nested within the destination
is created,
and the lifetime of <i>o</i> begins before the copy is performed.</ins>
   </blockquote>
   <h3 class="heading settled" data-level="5.9" id="191092-static-member-functions-allocatortraitsmembers"><span class="secno">5.9. </span><span class="content">19.10.9.2 Static member functions [allocator.traits.members]</span><a class="self-link" href="#191092-static-member-functions-allocatortraitsmembers"></a></h3>
   <p>Add paragraph after 19.10.9.2 [allocator.traits.members] paragraph 1:</p>
   <blockquote>
    <ins><i>Remarks:</i> Implicitly creates objects (6.6.2 [intro.object])
in the returned region of storage.</ins>
   </blockquote>
   <p>Add paragraph after 19.10.9.2 [allocator.traits.members] paragraph 2:</p>
   <blockquote>
    <ins><i>Remarks:</i> Implicitly creates objects (6.6.2 [intro.object])
in the returned region of storage.</ins>
   </blockquote>
   <h3 class="heading settled" data-level="5.10" id="191012-c-library-memory-allocation-cmalloc"><span class="secno">5.10. </span><span class="content">19.10.12 C library memory allocation [c.malloc]</span><a class="self-link" href="#191012-c-library-memory-allocation-cmalloc"></a></h3>
   <p>Add a new paragraph after [c.malloc] paragraph 4 in the description of <code class="highlight"><c- n>aligned_alloc</c-></code>, <code class="highlight"><c- n>calloc</c-></code>, <code class="highlight"><c- n>malloc</c-></code>, and <code class="highlight"><c- n>realloc</c-></code>:</p>
   <blockquote>
    <ins>These functions implicitly create objects (6.6.2 [intro.object])
in the returned region of storage. In the case of <code class="highlight"><c- n>calloc</c-></code> and <code class="highlight"><c- n>realloc</c-></code>,
the objects are created before the storage is zeroed or copied,
respectively.</ins>
   </blockquote>
   <h3 class="heading settled" data-level="5.11" id="2053-header-cstring-synopsis-cstringsyn"><span class="secno">5.11. </span><span class="content">20.5.3 Header <code class="highlight"><c- o>&lt;</c-><c- n>cstring</c-><c- o>></c-></code> synopsis [cstring.syn]</span><a class="self-link" href="#2053-header-cstring-synopsis-cstringsyn"></a></h3>
   <p>Change in 20.5.3 [cstring.syn] paragraph 3:</p>
   <blockquote>
    <p>
     The functions <code class="highlight"><c- n>memcpy</c-></code> and <code class="highlight"><c- n>memmove</c-></code> are signal-safe (16.12.4). 
     <ins> Both functions implicitly create objects (6.6.2 [intro.objects])
in the destination region of storage
immediately prior to copying the sequence of characters to the destination.</ins>
    </p>
   </blockquote>
   <div class="advisement">
     <b>Library extension, not for inclusion in C++20.</b> 
    <h3 class="heading settled" data-level="5.12" id="20102-header-memory-synopsis-memorysyn"><span class="secno">5.12. </span><span class="content">20.10.2 Header <code class="highlight"><c- o>&lt;</c-><c- n>memory</c-><c- o>></c-></code> synopsis [memory.syn]</span><a class="self-link" href="#20102-header-memory-synopsis-memorysyn"></a></h3>
    <p>Add the following after the declarations of <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>align</c-></code> and <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>assume_aligned</c-></code>:</p>
    <blockquote>
     <ins>
<pre class="highlight" style="color: #000; background-color: #c8ffc8"><c- c1>// [obj.lifetime] Explicit lifetime management</c->
<c- k>template</c-><typename t> <c- n>T</c-> <c- o>*</c-><c- n>std</c-><c- o>::</c-><c- n>start_lifetime_as</c-><c- p>(</c-><c- b>void</c-> <c- o>*</c-><c- n>p</c-><c- p>);</c->
<c- k>template</c-><typename t> <c- k>volatile</c-> <c- n>T</c-> <c- o>*</c-><c- n>std</c-><c- o>::</c-><c- n>start_lifetime_as</c-><c- p>(</c-><c- k>volatile</c-> <c- b>void</c-> <c- o>*</c-><c- n>p</c-><c- p>);</c->
</typename></typename></pre>
     </ins>
    </blockquote>
    <p>Add the following subclause immediately after 20.10.6 [ptr.align]:</p>
    <h3 class="heading settled" data-level="5.13" id="2010x-explicit-lifetime-management-objlifetime"><span class="secno">5.13. </span><span class="content">20.10.x <ins>Explicit lifetime management</ins> [obj.lifetime]</span><a class="self-link" href="#2010x-explicit-lifetime-management-objlifetime"></a></h3>
    <blockquote>
     <ins>
<pre class="highlight" style="color: #000; background-color: #c8ffc8"><c- k>template</c-><typename t> <c- n>T</c-> <c- o>*</c-><c- n>std</c-><c- o>::</c-><c- n>start_lifetime_as</c-><c- p>(</c-><c- b>void</c-> <c- o>*</c-><c- n>p</c-><c- p>);</c->
<c- k>template</c-><typename t> <c- k>volatile</c-> <c- n>T</c-> <c- o>*</c-><c- n>std</c-><c- o>::</c-><c- n>start_lifetime_as</c-><c- p>(</c-><c- k>volatile</c-> <c- b>void</c-> <c- o>*</c-><c- n>p</c-><c- p>);</c->
</typename></typename></pre>
     </ins>
    </blockquote>
    <blockquote>
     <ins><em>Mandates:</em> <code class="highlight"><c- n>T</c-></code> is an implicit-lifetime type. </ins>
    </blockquote>
    <blockquote>
     <ins><em>Requires:</em> [<code class="highlight"><c- n>p</c-></code>, <code class="highlight"><c- p>(</c-><c- b>char</c-><c- o>*</c-><c- p>)</c-><c- n>p</c-> <c- o>+</c-> <c- k>sizeof</c-><c- p>(</c-><c- n>T</c-><c- p>)</c-></code>) denotes a region of allocated
storage that is a subset of the region of storage reachable through <code class="highlight"><c- n>p</c-></code>.</ins>
    </blockquote>
    <blockquote>
     <ins><em>Effects:</em> Implicitly creates objects within the denoted region,
including an object <code class="highlight"><c- n>A</c-></code> of type <code class="highlight"><c- n>T</c-></code> whose address is <code class="highlight"><c- n>p</c-></code>. The object
representation of <code class="highlight"><c- n>A</c-></code> is the contents of the storage prior to the
call to <code class="highlight"><c- n>start_lifetime_as</c-></code> as if by calling <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>memcpy</c-></code> from a copy of the
original storage, except that the storage is not accessed.</ins>
    </blockquote>
    <blockquote>
     <ins><em>Returns:</em> A pointer to <code class="highlight"><c- n>A</c-></code>.</ins>
    </blockquote>
   </div>
   <h3 class="heading settled" data-level="5.14" id="2653-function-template-bit_cast-bitcast"><span class="secno">5.14. </span><span class="content">26.5.3 Function template <code class="highlight"><c- n>bit_cast</c-></code> [bit.cast]</span><a class="self-link" href="#2653-function-template-bit_cast-bitcast"></a></h3>
   <p>Change in 26.5.3 [bit.cast] paragraph 1:</p>
   <blockquote>
<pre class="highlight"><c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>To</c-><c- p>,</c-> <c- k>class</c-> <c- nc>From</c-><c- o>></c->
  <c- k>constexpr</c-> <c- n>To</c-> <c- n>bit_cast</c-><c- p>(</c-><c- k>const</c-> <c- n>From</c-><c- o>&amp;</c-> <c- n>from</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
</pre>
   </blockquote>
   <blockquote>
    <p><em>Returns:</em> An object of type <code class="highlight"><c- n>To</c-></code>.</p>
    <ins>Implicitly creates objects in the result (6.6.2 [intro.object]).</ins>
     Each bit of the value representation of the result
is equal to the corresponding bit in the object representation of <code class="highlight"><c- n>from</c-></code>.
Padding bits of the <code class="highlight"><c- n>To</c-></code> object are unspecified. 
    <ins>For the result and each object created within it, if</ins>
    <del>If</del>
     there is no value of 
    <ins>the object’s</ins>
     type 
    <del><code class="highlight"><c- n>To</c-></code></del>
     corresponding to the value representation produced, the behavior is undefined.
If there are multiple such values, which value is produced is unspecified. 
   </blockquote>
   <h3 class="heading settled" data-level="5.15" id="c5-c-and-iso-c-2017-diffcpp17"><span class="secno">5.15. </span><span class="content">C.5 C++ and ISO C++ 2017 [diff.cpp17]</span><a class="self-link" href="#c5-c-and-iso-c-2017-diffcpp17"></a></h3>
   <p>Add an entry to Annex C as follows:</p>
   <blockquote>
    <ins>
      <strong>Affected subclause:</strong> [basic.life]<br> <strong>Change:</strong> A pseudo-destructor call ends the lifetime of the object to
which it is applied.<br> <strong>Rationale:</strong> Increase consistency of the language model.<br> <strong>Effect on original feature:</strong> Valid ISO C++ 2017 code may be ill-formed
or have undefined behavior in this International Standard.<br> 
<pre class="highlight" style="color: #000; background-color: #c8ffc8"><c- k>constexpr</c-> <c- b>int</c-> <c- nf>f</c-><c- p>()</c-> <c- p>{</c->
  <c- b>int</c-> <c- n>a</c-> <c- o>=</c-> <c- mi>123</c-><c- p>;</c->
  <c- k>using</c-> <c- n>T</c-> <c- o>=</c-> <c- b>int</c-><c- p>;</c->
  <c- n>a</c-><c- p>.</c-><c- o>~</c-><c- n>T</c-><c- p>();</c->
  <c- k>return</c-> <c- n>a</c-><c- p>;</c->  <c- c1>// undefined behavior; previously returned 123</c->
<c- p>}</c->
<c- k>static_assert</c-><c- p>(</c-><c- n>f</c-><c- p>()</c-> <c- o>==</c-> <c- mi>123</c-><c- p>);</c->  <c- c1>// ill-formed; previously valid</c->
</pre>
    </ins>
   </blockquote>
   <h3 class="heading settled" data-level="5.16" id="feature-test-macro"><span class="secno">5.16. </span><span class="content">Feature test macro</span><a class="self-link" href="#feature-test-macro"></a></h3>
   <p>No feature test macro is proposed for the core language changes.</p>
   <div class="advisement">
     <b>Library extension, not for inclusion in C++20.</b> 
    <p>For the library functionality, add feature test macro <code class="highlight"><c- n>__cpp_lib_start_lifetime_at</c-></code> for header <code class="highlight"><c- o>&lt;</c-><c- n>memory</c-><c- o>></c-></code> with a suitable value to
Table 36 in 17.3.1 [support.limits.general].</p>
   </div>
   <h2 class="heading settled" data-level="6" id="acknowledgments"><span class="secno">6. </span><span class="content">Acknowledgments</span><a class="self-link" href="#acknowledgments"></a></h2>
   <p>Thanks to Ville Voutilainen for raising this problem, and to the members of
SG12 for discussing possible solutions.</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-c236">[C236]
   <dd>Raymond Mak. <a href="http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_236.htm">C Defect Report #236: The interpretation of type based aliasing rule when applied to union objects or allocated objects.</a>. URL: <a href="http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_236.htm">http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_236.htm</a>
   <dt id="biblio-p0083r3">[P0083R3]
   <dd>Alan Talbot, Jonathan Wakely, Howard Hinnant, James Dennett. <a href="https://wg21.link/p0083r3">Splicing Maps and Sets (Revision 5)</a>. 24 June 2016. URL: <a href="https://wg21.link/p0083r3">https://wg21.link/p0083r3</a>
   <dt id="biblio-p0593r0">[P0593R0]
   <dd>Ville Voutilainen. <a href="https://wg21.link/p0593r0">What to do with buffers that are not arrays, and undefined behavior thereof?</a>. 5 February 2017. URL: <a href="https://wg21.link/p0593r0">https://wg21.link/p0593r0</a>
   <dt id="biblio-p0593r1">[P0593R1]
   <dd>Richard Smith, Ville Voutilainen. <a href="https://wg21.link/p0593r1">Implicit creation of objects for low-level object manipulation</a>. 16 October 2017. URL: <a href="https://wg21.link/p0593r1">https://wg21.link/p0593r1</a>
   <dt id="biblio-p0593r2">[P0593R2]
   <dd>Richard Smith. <a href="https://wg21.link/p0593r2">Implicit creation of objects for low-level object manipulation</a>. 11 February 2018. URL: <a href="https://wg21.link/p0593r2">https://wg21.link/p0593r2</a>
   <dt id="biblio-p0593r3">[P0593R3]
   <dd>Richard Smith. <a href="https://wg21.link/p0593r3">Implicit creation of objects for low-level object manipulation</a>. 18 January 2019. URL: <a href="https://wg21.link/p0593r3">https://wg21.link/p0593r3</a>
  </dl>