<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang xml:lang>
<head>
  <meta charset="utf-8" />
  <meta name="generator" content="mpark/wg21" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
  <meta name="dcterms.date" content="2024-01-08" />
  <title>Disallow Binding a Returned Glvalue to a Temporary</title>
  <style>
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
div.csl-block{margin-left: 1.5em;}
ul.task-list{list-style: none;}
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
.sourceCode { overflow: visible; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre > code.sourceCode { white-space: pre-wrap; }
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
{ counter-reset: source-line 0; }
pre.numberSource code > span
{ position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code > span > a:first-child::before
{ content: counter(source-line);
position: relative; left: -1em; text-align: right; vertical-align: baseline;
border: none; display: inline-block;
-webkit-touch-callout: none; -webkit-user-select: none;
-khtml-user-select: none; -moz-user-select: none;
-ms-user-select: none; user-select: none;
padding: 0 4px; width: 4em;
color: #aaaaaa;
}
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; }
div.sourceCode
{ background-color: #f6f8fa; }
@media screen {
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
}
code span { } 
code span.al { color: #ff0000; } 
code span.an { } 
code span.at { } 
code span.bn { color: #9f6807; } 
code span.bu { color: #9f6807; } 
code span.cf { color: #00607c; } 
code span.ch { color: #9f6807; } 
code span.cn { } 
code span.co { color: #008000; font-style: italic; } 
code span.cv { color: #008000; font-style: italic; } 
code span.do { color: #008000; } 
code span.dt { color: #00607c; } 
code span.dv { color: #9f6807; } 
code span.er { color: #ff0000; font-weight: bold; } 
code span.ex { } 
code span.fl { color: #9f6807; } 
code span.fu { } 
code span.im { } 
code span.in { color: #008000; } 
code span.kw { color: #00607c; } 
code span.op { color: #af1915; } 
code span.ot { } 
code span.pp { color: #6f4e37; } 
code span.re { } 
code span.sc { color: #9f6807; } 
code span.ss { color: #9f6807; } 
code span.st { color: #9f6807; } 
code span.va { } 
code span.vs { color: #9f6807; } 
code span.wa { color: #008000; font-weight: bold; } 
code.diff {color: #898887}
code.diff span.va {color: #006e28}
code.diff span.st {color: #bf0303}
</style>
  <style type="text/css">
body {
margin: 5em;
font-family: serif;

hyphens: auto;
line-height: 1.35;
text-align: justify;
}
@media screen and (max-width: 30em) {
body {
margin: 1.5em;
}
}
div.wrapper {
max-width: 60em;
margin: auto;
}

ul {
list-style-type: none;
padding-left: 2.5em;
margin-top: -0.2em;
margin-bottom: -0.2em;
}
ol {
padding-left: 2.5em;
}
a {
text-decoration: none;
color: #4183C4;
}
a.hidden_link {
text-decoration: none;
color: inherit;
}
li {
margin-top: 0.6em;
margin-bottom: 0.6em;
}
h1, h2, h3, h4 {
position: relative;
line-height: 1;
}
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;
font-family: sans-serif;
font-weight: normal;
font-size: 83%;
}
a.self-link:hover { opacity: 1; }
a.self-link::before { content: "§"; }
ul > li:before {
content: "\2014";
position: absolute;
margin-left: -1.5em;
}

#TOC ul > li:before {
content: none;
}
#TOC > ul {
padding-left: 0;
}

.toc-section-number {
margin-right: 0.5em;
}
:target { background-color: #C9FBC9; }
:target .codeblock { background-color: #C9FBC9; }
:target ul { background-color: #C9FBC9; }
.abbr_ref { float: right; }
.folded_abbr_ref { float: right; }
:target .folded_abbr_ref { display: none; }
:target .unfolded_abbr_ref { float: right; display: inherit; }
.unfolded_abbr_ref { display: none; }
.secnum { display: inline-block; min-width: 35pt; }
.header-section-number { display: inline-block; min-width: 35pt; }
.annexnum { display: block; }
div.sourceLinkParent {
float: right;
}
a.sourceLink {
position: absolute;
opacity: 0;
margin-left: 10pt;
}
a.sourceLink:hover {
opacity: 1;
}
a.itemDeclLink {
position: absolute;
font-size: 75%;
text-align: right;
width: 5em;
opacity: 0;
}
a.itemDeclLink:hover { opacity: 1; }
span.marginalizedparent {
position: relative;
left: -5em;
}
li span.marginalizedparent { left: -7em; }
li ul > li span.marginalizedparent { left: -9em; }
li ul > li ul > li span.marginalizedparent { left: -11em; }
li ul > li ul > li ul > li span.marginalizedparent { left: -13em; }
div.footnoteNumberParent {
position: relative;
left: -4.7em;
}
a.marginalized {
position: absolute;
font-size: 75%;
text-align: right;
width: 5em;
}
a.enumerated_item_num {
position: relative;
left: -3.5em;
display: inline-block;
margin-right: -3em;
text-align: right;
width: 3em;
}
div.para { margin-bottom: 0.6em; margin-top: 0.6em; text-align: justify; }
div.section { text-align: justify; }
div.sentence { display: inline; }
span.indexparent {
display: inline;
position: relative;
float: right;
right: -1em;
}
a.index {
position: absolute;
display: none;
}
a.index:before { content: "⟵"; }

a.index:target {
display: inline;
}
.indexitems {
margin-left: 2em;
text-indent: -2em;
}
div.itemdescr {
margin-left: 3em;
}
.bnf {
font-family: serif;
margin-left: 40pt;
margin-top: 0.5em;
margin-bottom: 0.5em;
}
.ncbnf {
font-family: serif;
margin-top: 0.5em;
margin-bottom: 0.5em;
margin-left: 40pt;
}
.ncsimplebnf {
font-family: serif;
font-style: italic;
margin-top: 0.5em;
margin-bottom: 0.5em;
margin-left: 40pt;
background: inherit; 
}
span.textnormal {
font-style: normal;
font-family: serif;
white-space: normal;
display: inline-block;
}
span.rlap {
display: inline-block;
width: 0px;
}
span.descr { font-style: normal; font-family: serif; }
span.grammarterm { font-style: italic; }
span.term { font-style: italic; }
span.terminal { font-family: monospace; font-style: normal; }
span.nonterminal { font-style: italic; }
span.tcode { font-family: monospace; font-style: normal; }
span.textbf { font-weight: bold; }
span.textsc { font-variant: small-caps; }
a.nontermdef { font-style: italic; font-family: serif; }
span.emph { font-style: italic; }
span.techterm { font-style: italic; }
span.mathit { font-style: italic; }
span.mathsf { font-family: sans-serif; }
span.mathrm { font-family: serif; font-style: normal; }
span.textrm { font-family: serif; }
span.textsl { font-style: italic; }
span.mathtt { font-family: monospace; font-style: normal; }
span.mbox { font-family: serif; font-style: normal; }
span.ungap { display: inline-block; width: 2pt; }
span.textit { font-style: italic; }
span.texttt { font-family: monospace; }
span.tcode_in_codeblock { font-family: monospace; font-style: normal; }
span.phantom { color: white; }

span.math { font-style: normal; }
span.mathblock {
display: block;
margin-left: auto;
margin-right: auto;
margin-top: 1.2em;
margin-bottom: 1.2em;
text-align: center;
}
span.mathalpha {
font-style: italic;
}
span.synopsis {
font-weight: bold;
margin-top: 0.5em;
display: block;
}
span.definition {
font-weight: bold;
display: block;
}
.codeblock {
margin-left: 1.2em;
line-height: 127%;
}
.outputblock {
margin-left: 1.2em;
line-height: 127%;
}
div.itemdecl {
margin-top: 2ex;
}
code.itemdeclcode {
white-space: pre;
display: block;
}
span.textsuperscript {
vertical-align: super;
font-size: smaller;
line-height: 0;
}
.footnotenum { vertical-align: super; font-size: smaller; line-height: 0; }
.footnote {
font-size: small;
margin-left: 2em;
margin-right: 2em;
margin-top: 0.6em;
margin-bottom: 0.6em;
}
div.minipage {
display: inline-block;
margin-right: 3em;
}
div.numberedTable {
text-align: center;
margin: 2em;
}
div.figure {
text-align: center;
margin: 2em;
}
table {
border: 1px solid black;
border-collapse: collapse;
margin-left: auto;
margin-right: auto;
margin-top: 0.8em;
text-align: left;
hyphens: none; 
}
td, th {
padding-left: 1em;
padding-right: 1em;
vertical-align: top;
}
td.empty {
padding: 0px;
padding-left: 1px;
}
td.left {
text-align: left;
}
td.right {
text-align: right;
}
td.center {
text-align: center;
}
td.justify {
text-align: justify;
}
td.border {
border-left: 1px solid black;
}
tr.rowsep, td.cline {
border-top: 1px solid black;
}
tr.even, tr.odd {
border-bottom: 1px solid black;
}
tr.capsep {
border-top: 3px solid black;
border-top-style: double;
}
tr.header {
border-bottom: 3px solid black;
border-bottom-style: double;
}
th {
border-bottom: 1px solid black;
}
span.centry {
font-weight: bold;
}
div.table {
display: block;
margin-left: auto;
margin-right: auto;
text-align: center;
width: 90%;
}
span.indented {
display: block;
margin-left: 2em;
margin-bottom: 1em;
margin-top: 1em;
}
ol.enumeratea { list-style-type: none; background: inherit; }
ol.enumerate { list-style-type: none; background: inherit; }

code.sourceCode > span { display: inline; }
</style>
  <link href="data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAVoJEAN6CRADegkQAWIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wCCRAAAgkQAAIJEAACCRAAsgkQAvoJEAP+CRAD/gkQA/4JEAP+CRADAgkQALoJEAACCRAAAgkQAAP///wD///8AgkQAAIJEABSCRACSgkQA/IJEAP99PQD/dzMA/3czAP99PQD/gkQA/4JEAPyCRACUgkQAFIJEAAD///8A////AHw+AFiBQwDqgkQA/4BBAP9/PxP/uZd6/9rJtf/bybX/upd7/39AFP+AQQD/gkQA/4FDAOqAQgBc////AP///wDKklv4jlEa/3o7AP+PWC//8+3o///////////////////////z7un/kFox/35AAP+GRwD/mVYA+v///wD///8A0Zpk+NmibP+0d0T/8evj///////+/fv/1sKz/9bCs//9/fr//////+/m2/+NRwL/nloA/5xYAPj///8A////ANKaZPjRmGH/5cKh////////////k149/3UwAP91MQD/lmQ//86rhv+USg3/m1YA/5hSAP+bVgD4////AP///wDSmmT4zpJY/+/bx///////8+TV/8mLT/+TVx//gkIA/5lVAP+VTAD/x6B//7aEVv/JpH7/s39J+P///wD///8A0ppk+M6SWP/u2sf///////Pj1f/Nj1T/2KFs/8mOUv+eWhD/lEsA/8aee/+0glT/x6F7/7J8Rvj///8A////ANKaZPjRmGH/48Cf///////+/v7/2qt//82PVP/OkFX/37KJ/86siv+USg7/mVQA/5hRAP+bVgD4////AP///wDSmmT40ppk/9CVXP/69O////////7+/v/x4M//8d/P//7+/f//////9u7n/6tnJf+XUgD/nFgA+P///wD///8A0ppk+NKaZP/RmWL/1qNy//r07///////////////////////+vXw/9akdP/Wnmn/y5FY/6JfFvj///8A////ANKaZFTSmmTo0ppk/9GYYv/Ql1//5cWm//Hg0P/x4ND/5cWm/9GXYP/RmGH/0ppk/9KaZOjVnmpY////AP///wDSmmQA0ppkEtKaZI7SmmT60ppk/9CWX//OkVb/zpFW/9CWX//SmmT/0ppk/NKaZJDSmmQS0ppkAP///wD///8A0ppkANKaZADSmmQA0ppkKtKaZLrSmmT/0ppk/9KaZP/SmmT/0ppkvNKaZCrSmmQA0ppkANKaZAD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkUtKaZNzSmmTc0ppkVNKaZADSmmQA0ppkANKaZADSmmQA////AP5/AAD4HwAA4AcAAMADAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAMADAADgBwAA+B8AAP5/AAAoAAAAIAAAAEAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wCCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAAyCRACMgkQA6oJEAOqCRACQgkQAEIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wD///8A////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRABigkQA5oJEAP+CRAD/gkQA/4JEAP+CRADqgkQAZoJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAAD///8A////AP///wD///8AgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAA4gkQAwoJEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQAxIJEADyCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAP///wD///8A////AP///wCCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAWgkQAmIJEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAJyCRAAYgkQAAIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wD///8A////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAdIJEAPCCRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAPSCRAB4gkQAAIJEAACCRAAAgkQAAIJEAAD///8A////AP///wD///8AgkQAAIJEAACCRAAAgkQASoJEANKCRAD/gkQA/4JEAP+CRAD/g0YA/39AAP9zLgD/bSQA/2shAP9rIQD/bSQA/3MuAP9/PwD/g0YA/4JEAP+CRAD/gkQA/4JEAP+CRADUgkQAToJEAACCRAAAgkQAAP///wD///8A////AP///wB+PwAAgkUAIoJEAKiCRAD/gkQA/4JEAP+CRAD/hEcA/4BBAP9sIwD/dTAA/5RfKv+viF7/vp56/76ee/+wiF7/lWAr/3YxAP9sIwD/f0AA/4RHAP+CRAD/gkQA/4JEAP+CRAD/gkQArIJEACaBQwAA////AP///wD///8A////AIBCAEBzNAD6f0EA/4NFAP+CRAD/gkQA/4VIAP92MwD/bSUA/6N1Tv/ezsL/////////////////////////////////38/D/6V3Uv9uJgD/dTEA/4VJAP+CRAD/gkQA/4JEAP+BQwD/fUAA/4FDAEj///8A////AP///wD///8AzJRd5qBlKf91NgD/dDUA/4JEAP+FSQD/cy4A/3YyAP/PuKP//////////////////////////////////////////////////////9K7qP94NQD/ciwA/4VJAP+CRAD/fkEA/35BAP+LSwD/mlYA6v///wD///8A////AP///wDdpnL/4qx3/8KJUv+PUhf/cTMA/3AsAP90LgD/4dK+/////////////////////////////////////////////////////////////////+TYxf91MAD/dTIA/31CAP+GRwD/llQA/6FcAP+gWwD8////AP///wD///8A////ANGZY/LSm2X/4ap3/92mcP+wdT3/byQA/8mwj////////////////////////////////////////////////////////////////////////////+LYxv9zLgP/jUoA/59bAP+hXAD/nFgA/5xYAPL///8A////AP///wD///8A0ppk8tKaZP/RmWL/1p9q/9ubXv/XqXj////////////////////////////7+fD/vZyG/6BxS/+gcUr/vJuE//r37f//////////////////////3MOr/5dQBf+dVQD/nVkA/5xYAP+cWAD/nFgA8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/SmWP/yohJ//jo2P//////////////////////4NTG/4JDFf9lGAD/bSQA/20kAP9kGAD/fz8S/+Xb0f//////5NG9/6txN/+LOgD/m1QA/51aAP+cWAD/m1cA/5xYAP+cWADy////AP///wD///8A////ANKaZPLSmmT/0ppk/8+TWf/Unmv//v37//////////////////////+TWRr/VwsA/35AAP+ERgD/g0UA/4JGAP9lHgD/kFga/8KXX/+TRwD/jT4A/49CAP+VTQD/n10A/5xYAP+OQQD/lk4A/55cAPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/y4tO/92yiP//////////////////////8NnE/8eCQP+rcTT/ez0A/3IyAP98PgD/gEMA/5FSAP+USwD/jj8A/5lUAP+JNwD/yqV2/694Mf+HNQD/jkAA/82rf/+laBj/jT4A8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/LiUr/4byY///////////////////////gupX/0I5P/+Wuev/Lklz/l1sj/308AP+QSwD/ol0A/59aAP+aVQD/k0oA/8yoh///////+fXv/6pwO//Lp3v///////Pr4f+oay7y////AP///wD///8A////ANKaZPLSmmT/0ppk/8uJSv/hvJj//////////////////////+G7l//Jhkb/0ppk/96nc//fqXX/x4xO/6dkFP+QSQD/llEA/5xXAP+USgD/yaOA///////38uv/qG05/8ijdv//////8efb/6ZpLPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/zIxO/9yxh///////////////////////7dbA/8iEQf/Sm2X/0Zlj/9ScZv/eqHf/2KJv/7yAQf+XTgD/iToA/5lSAP+JNgD/yKFv/611LP+HNQD/jT8A/8qmeP+kZRT/jT4A8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/Pk1n/1J5q//78+//////////////////+/fv/1aFv/8iEQv/Tm2b/0ppl/9GZY//Wn2z/1pZc/9eldf/Bl2b/kUcA/4w9AP+OQAD/lUwA/59eAP+cWQD/jT8A/5ZOAP+eXADy////AP///wD///8A////ANKaZPLSmmT/0ppk/9KZY//KiEn/8d/P///////////////////////47+f/05tm/8iCP//KiEj/yohJ/8eCP//RmGH//vfy///////n1sP/rXQ7/4k4AP+TTAD/nVoA/5xYAP+cVwD/nFgA/5xYAPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/0ptl/8uLTf/aq37////////////////////////////+/fz/6c2y/961jv/etY7/6Myx//78+v//////////////////////3MWv/5xXD/+ORAD/mFQA/51ZAP+cWAD/nFgA8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/SmmT/0ppk/8mFRP/s1b//////////////////////////////////////////////////////////////////////////////+PD/0JFU/7NzMv+WUQD/kUsA/5tXAP+dWQDy////AP///wD///8A////ANKaZP/SmmT/0ppk/9KaZP/Sm2X/z5NZ/8yMT//z5NX/////////////////////////////////////////////////////////////////9Ofa/8yNUP/UmGH/36p5/8yTWv+qaSD/kksA/5ROAPz///8A////AP///wD///8A0ppk5NKaZP/SmmT/0ppk/9KaZP/TnGf/zY9T/82OUv/t1sD//////////////////////////////////////////////////////+7Yw//OkFX/zI5R/9OcZ//SmmP/26V0/9ymdf/BhUf/ol8R6P///wD///8A////AP///wDSmmQ80ppk9tKaZP/SmmT/0ppk/9KaZP/TnGj/zpFW/8qJSv/dson/8uHS//////////////////////////////////Lj0//etIv/y4lL/86QVf/TnGj/0ppk/9KaZP/RmWP/05xn/9ymdfjUnWdC////AP///wD///8A////ANKaZADSmmQc0ppkotKaZP/SmmT/0ppk/9KaZP/Tm2b/0Zli/8qJSf/NjlH/16Z3/+G8mP/myKr/5siq/+G8mP/Xp3f/zY5S/8qISf/RmGH/05tm/9KaZP/SmmT/0ppk/9KaZP/SmmSm0pljINWdaQD///8A////AP///wD///8A0ppkANKaZADSmmQA0ppkQtKaZMrSmmT/0ppk/9KaZP/SmmT/0ptl/9GYYf/Nj1P/y4lL/8qISP/KiEj/y4lK/82PU//RmGH/0ptl/9KaZP/SmmT/0ppk/9KaZP/SmmTO0ppkRtKaZADSmmQA0ppkAP///wD///8A////AP///wDSmmQA0ppkANKaZADSmmQA0ppkANKaZGzSmmTu0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmTw0ppkcNKaZADSmmQA0ppkANKaZADSmmQA////AP///wD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZBLSmmSQ0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppklNKaZBTSmmQA0ppkANKaZADSmmQA0ppkANKaZAD///8A////AP///wD///8A0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQy0ppkutKaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppkvtKaZDbSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkAP///wD///8A////AP///wDSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkXNKaZODSmmT/0ppk/9KaZP/SmmT/0ppk5NKaZGDSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA////AP///wD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkBtKaZIbSmmTo0ppk6tKaZIrSmmQK0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZAD///8A////AP/8P///+B///+AH//+AAf//AAD//AAAP/AAAA/gAAAHwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA+AAAAfwAAAP/AAAP/8AAP//gAH//+AH///4H////D//" rel="icon" />
  
  <!--[if lt IE 9]>
    <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
  <![endif]-->
</head>
<body>
<div class="wrapper">
<header id="title-block-header">
<h1 class="title" style="text-align:center">Disallow Binding a Returned
Glvalue to a Temporary</h1>
<table style="border:none;float:right">
  <tr>
    <td>Document #:</td>
    <td>P2748R4</td>
  </tr>
  <tr>
    <td>Date:</td>
    <td>2024-01-08</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Project:</td>
    <td>Programming Language C++</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Audience:</td>
    <td>
      Core<br>
    </td>
  </tr>
  <tr>
    <td style="vertical-align:top">Reply-to:</td>
    <td>
      Brian Bi<br>&lt;<a href="mailto:bbi10@bloomberg.net" class="email">bbi10@bloomberg.net</a>&gt;<br>
    </td>
  </tr>
</table>
</header>
<div style="clear:both">
<div id="TOC" role="doc-toc">
<h1 id="toctitle">Contents</h1>
<ul>
<li><a href="#revision-history" id="toc-revision-history"><span class="toc-section-number">1</span> Revision history</a>
<ul>
<li><a href="#r4" id="toc-r4"><span class="toc-section-number">1.1</span> R4</a></li>
<li><a href="#r3" id="toc-r3"><span class="toc-section-number">1.2</span> R3</a></li>
<li><a href="#r2" id="toc-r2"><span class="toc-section-number">1.3</span> R2</a></li>
<li><a href="#r1" id="toc-r1"><span class="toc-section-number">1.4</span> R1</a></li>
</ul></li>
<li><a href="#introduction" id="toc-introduction"><span class="toc-section-number">2</span> Introduction</a></li>
<li><a href="#background" id="toc-background"><span class="toc-section-number">3</span> Background</a></li>
<li><a href="#proposal" id="toc-proposal"><span class="toc-section-number">4</span> Proposal</a></li>
<li><a href="#what-about-unevaluated-return-statements" id="toc-what-about-unevaluated-return-statements"><span class="toc-section-number">5</span> What about unevaluated
<code class="sourceCode default">return</code> statements?</a></li>
<li><a href="#impact-on-stdis_convertible" id="toc-impact-on-stdis_convertible"><span class="toc-section-number">6</span> Impact on
<code class="sourceCode default">std::is_convertible</code></a></li>
<li><a href="#implementation-experience" id="toc-implementation-experience"><span class="toc-section-number">7</span> Implementation experience</a></li>
<li><a href="#wording" id="toc-wording"><span class="toc-section-number">8</span> Wording</a></li>
<li><a href="#bibliography" id="toc-bibliography"><span class="toc-section-number">9</span> References</a></li>
</ul>
</div>
<h1 data-number="1" id="revision-history"><span class="header-section-number">1</span> Revision history<a href="#revision-history" class="self-link"></a></h1>
<h2 data-number="1.1" id="r4"><span class="header-section-number">1.1</span> R4<a href="#r4" class="self-link"></a></h2>
<ul>
<li>Restored carve-out for
<code class="sourceCode default">std::is_convertible</code>.</li>
<li>Corrected inaccuracies in discussion of LWG issue 3400.</li>
</ul>
<h2 data-number="1.2" id="r3"><span class="header-section-number">1.2</span> R3<a href="#r3" class="self-link"></a></h2>
<ul>
<li>Changed wording slightly to reflect that references bind to objects,
not expressions.</li>
<li>Removed carve-out for
<code class="sourceCode default">std::is_convertible</code> following
CWG review.</li>
</ul>
<h2 data-number="1.3" id="r2"><span class="header-section-number">1.3</span> R2<a href="#r2" class="self-link"></a></h2>
<ul>
<li>Removed library wording and added a carve-out to core wording</li>
<li>Added discussion of implementation experience</li>
</ul>
<h2 data-number="1.4" id="r1"><span class="header-section-number">1.4</span> R1<a href="#r1" class="self-link"></a></h2>
<ul>
<li>Added another motivating example</li>
<li>Added discussion of unevaluated contexts</li>
<li>Added library wording</li>
</ul>
<h1 data-number="2" id="introduction"><span class="header-section-number">2</span> Introduction<a href="#introduction" class="self-link"></a></h1>
<p>The following code contains a bug: The code initializes a reference
from an object of a different type — the programmer has forgotten that
the first element of the pair is
<code class="sourceCode default">const</code> — and creates a temporary.
As a result, the reference
<code class="sourceCode default">d_first</code> is always dangling:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> X <span class="op">{</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> std<span class="op">::</span>map<span class="op">&lt;</span>std<span class="op">::</span>string, <span class="dt">int</span><span class="op">&gt;</span> d_map;</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> std<span class="op">::</span>pair<span class="op">&lt;</span>std<span class="op">::</span>string, <span class="dt">int</span><span class="op">&gt;&amp;</span> d_first;</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>    X<span class="op">(</span><span class="kw">const</span> std<span class="op">::</span>map<span class="op">&lt;</span>std<span class="op">::</span>string, <span class="dt">int</span><span class="op">&gt;&amp;</span> map<span class="op">)</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>        <span class="op">:</span> d_map<span class="op">(</span>map<span class="op">)</span>, d_first<span class="op">(*</span>d_map<span class="op">.</span>begin<span class="op">())</span> <span class="op">{}</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
<p>Luckily, the above code is actually ill formed (§ <span>11.9.3
<a href="https://wg21.link/N4971#class.base.init">[class.base.init]</a><a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a></span>p8 of the Standard).
Nonetheless, valid code can contain essentially the same bug:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> Y <span class="op">{</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>    std<span class="op">::</span>map<span class="op">&lt;</span>std<span class="op">::</span>string, <span class="dt">int</span><span class="op">&gt;</span> d_map;</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> std<span class="op">::</span>pair<span class="op">&lt;</span>std<span class="op">::</span>string, <span class="dt">int</span><span class="op">&gt;&amp;</span> first<span class="op">()</span> <span class="kw">const</span> <span class="op">{</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="op">*</span>d_map<span class="op">.</span>begin<span class="op">()</span>;</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
<p>This code is valid, although compilers might warn. Like the first
code snippet in this paper, this one always produces a dangling
reference. We should make this code likewise ill formed.</p>
<p>A colleague recently reported another example. A program appeared to
be accessing memory that was unsafe to access. The bug was ultimately
caused by the following function returning by reference though it should
not have:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> std<span class="op">::</span>string_view<span class="op">&amp;</span> getString<span class="op">()</span> <span class="op">{</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">static</span> std<span class="op">::</span>string s;</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> s;</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Finding this bug was difficult yet would have been easy if the
<code class="sourceCode default">return</code> statement were simply ill
formed.</p>
<h1 data-number="3" id="background"><span class="header-section-number">3</span> Background<a href="#background" class="self-link"></a></h1>
<p>In <span class="citation" data-cites="CWG1696">[<a href="#ref-CWG1696" role="doc-biblioref">CWG1696</a>]</span>, Richard
Smith pointed out that, though binding a reference member to a temporary
in a <em>mem-initializer</em> was explicitly called out in the Standard
as one of the cases in which the lifetime of the temporary is
<em>not</em> extended to the lifetime of the reference, no corresponding
wording was offered for the case in which the expression that produces
the temporary is supplied by a default member initializer.</p>
<p>Initially, the proposed resolution simply resolved the inconsistency
in favor of explicitly specifying that
<em>brace-or-equal-initializers</em> behave the same way as
<em>mem-initializers</em> (i.e., neither extends lifetime). However, at
the Issaquah meeting in 2014, making both ill formed was suggested. CWG
appears to have accepted this suggestion without controversy. (At the
Urbana-Champaign meeting later that year, Issue 1696 was given DR
status.)</p>
<p>This change was so uncontroversial because binding a reference to a
temporary, when the reference will outlive the temporary and become
dangling as soon as the full-expression completes, is always a bug. In
some simple cases, a novice programmer might not understand that a
temporary must be materialized when binding a reference to a prvalue. On
the other hand, the examples given in the introduction represent code
that experienced C++ developers can easily write.</p>
<h1 data-number="4" id="proposal"><span class="header-section-number">4</span> Proposal<a href="#proposal" class="self-link"></a></h1>
<p>The dangling reference created by
<code class="sourceCode default">X</code>’s constructor is always a bug,
and the same is true for the dangling reference created by
<code class="sourceCode default">Y::first</code>. In fact, one can
imagine some obscure situations in which binding a reference member to a
temporary in a <em>mem-initializer</em> could be useful to cache the
result of an expensive computation, which could then be used by later
<em>mem-initializers</em> and within the <em>compound-statement</em> of
the constructor. In contrast, when binding a returned glvalue to a
temporary, even such obscure, limited applications seem nonexistent.</p>
<p>I propose, therefore, to make binding a returned glvalue to a
temporary likewise ill formed.</p>
<p>Note that recent versions of Clang, GCC, and MSVC all issue warnings
that explain the creation of the dangling reference. The availability of
such warnings raises the question of whether programmers should simply
use compiler flags to convert those warnings into errors, thus obtaining
all the benefits of this proposal with no need for a language change.
However, at least in Clang and GCC, the warnings have false positives,
which (as discussed in Section 5) occur because they are less narrowly
scoped than this proposal. More broadly, compiler warnings are no
substitute for language rules because the warnings lack formal
specification and are not portable.</p>
<h1 data-number="5" id="what-about-unevaluated-return-statements"><span class="header-section-number">5</span> What about unevaluated
<code class="sourceCode default">return</code> statements?<a href="#what-about-unevaluated-return-statements" class="self-link"></a></h1>
<p>At the February 2023 meeting in Issaquah, the EWG asked for improved
wording related to unevaluated contexts. However, no such thing as an
unevaluated <code class="sourceCode default">return</code> statement
exists (at least from the core language point of view; see Section 6 for
discussion of the library).</p>
<p>Section <span>6.3
<a href="https://wg21.link/N4971#basic.def.odr">[basic.def.odr]</a></span>p3
of the Standard defines a conversion as <em>potentially evaluated</em>
unless it is “an unevaluated operand, a subexpression thereof, or a
conversion in an initialization or conversion sequence in such a
context.” Because a <code class="sourceCode default">return</code>
statement is not an expression statement, the only kind of expression a
<code class="sourceCode default">return</code> statement can appear
within is a lambda expression, but the statements in the body of a
lambda expression are not subexpressions of the lambda expression (§
<span>6.9.1
<a href="https://wg21.link/N4971#intro.execution">[intro.execution]</a></span>p3.3),
so even if the lambda expression is unevaluated, the statements in its
body are still potentially evaluated.</p>
<p>This definition is not simply a technicality but follows from the
very nature of function definitions in C++. When the body of a lambda
expression is instantiated, a function definition is created, and a
function definition created by an instantiation triggered from an
unevaluated context is no different from any other definition of the
same function. In particular, that function may be ODR-used at some
later point, but the compiler is not expected to instantiate it a second
time since the instantiation from an unevaluated context is as good as
any other instantiation. Attempting to carve out a narrow exemption that
applies exclusively to <code class="sourceCode default">return</code>
statements appearing lexically within lambda expressions that are not
potentially evaluated would, therefore, fail to actually prevent such
<code class="sourceCode default">return</code> statements from being
evaluated at run time.</p>
<p>For this reason, my proposal does not include carving out an
exemption for lambdas in unevaluated contexts. This exclusion raises the
question of whether the proposal would disallow some useful
metaprogramming techniques.</p>
<p><span class="citation" data-cites="P0315R2">[<a href="#ref-P0315R2" role="doc-biblioref">P0315R2</a>]</span> discusses two use cases for
lambdas in unevaluated contexts. In both use cases, the lambda is used
only for the signature of its function call operator. In such cases, the
<code class="sourceCode default">return</code> statement in the lambda
could be eliminated, and the lambda could be given a trailing return
type instead. Rewriting the code in this fashion is annoying but will be
necessary in only the tiny fraction of cases where lambdas in
unevaluated contexts currently contain
<code class="sourceCode default">return</code> statements that would
create dangling references if they were to be evaluated. The benefits of
this proposal outweigh the inconvenience that would be inflicted in
those very few cases.</p>
<p>As evidence that this situation is almost nonexistent, consider that
recent versions of Clang and GCC do not distinguish
<code class="sourceCode default">return</code> statements appearing in
unevaluated lambda expressions from those that appear in any other
function and will issue a warning even in cases such as the
following:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>std<span class="op">::</span>string_view sv;</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="kw">decltype</span> <span class="op">(</span> <span class="op">[]</span> <span class="op">()</span> <span class="op">-&gt;</span> <span class="kw">const</span> std<span class="op">::</span>string_view<span class="op">&amp;</span> <span class="op">{</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">static</span> std<span class="op">::</span>string s;</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> s;</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span> <span class="op">()</span> <span class="op">)</span> svr <span class="op">=</span> sv;</span></code></pre></div>
<p>I searched the Clang and GCC bug trackers for reports of false
positives for the
<code class="sourceCode default">-Wreturn-stack-address</code> and
<code class="sourceCode default">-Wreturn-local-addr</code> flags,
respectively. Some false positives were reported, but they generally
appear to be related to these warnings going far beyond the set of
situations that this paper proposes to make ill formed; the warnings
perform a flow analysis to check whether a returned pointer value might
have been derived directly or indirectly from the address of a temporary
or an automatic variable. <a href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100403">GCC bug
100403</a> and <a href="https://github.com/llvm/llvm-project/issues/43348">Clang bug
44003</a> are representative of this class of bugs. I found no issues in
which a user opined that the warning should not fire because the
<code class="sourceCode default">return</code> statement was in a lambda
expression in an unevaluated context.</p>
<h1 data-number="6" id="impact-on-stdis_convertible"><span class="header-section-number">6</span> Impact on
<code class="sourceCode default">std::is_convertible</code><a href="#impact-on-stdis_convertible" class="self-link"></a></h1>
<p>As pointed out at the February 2023 meeting in Issaquah, the current
definition of the
<code class="sourceCode default">std::is_convertible</code> type trait
(<span>21.3.7
<a href="https://wg21.link/N4971#meta.rel">[meta.rel]</a></span>p5)
depends on the well-formedness of a
<code class="sourceCode default">return</code> statement but is intended
to detect implicit convertibility in general. For this reason, this
proposal must ensure that the meaning of
<code class="sourceCode default">std::is_convertible</code> does not
change; for example, <code class="sourceCode default">std::is_convertible_v&lt;int, const double&amp;&gt;</code>
should continue to be <code class="sourceCode default">true</code>.</p>
<p>Since, as discussed previously, no such thing as an unevaluated
<code class="sourceCode default">return</code> statement exists, giving
a blanket exemption for such nonexistent entities is an impractical
solution to this problem. Instead, three possible approaches to
exempting <code class="sourceCode default">std::is_convertible</code>
from the rule proposed by this paper present themselves.</p>
<ol type="1">
<li>Add a special exception only for the Standard Library.</li>
<li>Re-express
<code class="sourceCode default">std::is_convertible</code> in terms of
a piece of code that does not contain a
<code class="sourceCode default">return</code> statement.</li>
<li>Re-express
<code class="sourceCode default">std::is_convertible</code> in terms of
the core language concept of implicit convertibility.</li>
</ol>
<p>The second approach is technically feasible and has been proposed in
<span class="citation" data-cites="LWG4028">[<a href="#ref-LWG4028" role="doc-biblioref">LWG4028</a>]</span>. However, since <span class="citation" data-cites="LWG3400">[<a href="#ref-LWG3400" role="doc-biblioref">LWG3400</a>]</span> and <span class="citation" data-cites="LWG4028">[<a href="#ref-LWG4028" role="doc-biblioref">LWG4028</a>]</span> remain unresolved, the LWG
could possibly decide that the specification of <code class="sourceCode default">std::is_nothrow_convertible&lt;From, To&gt;</code>
should exclude consideration of whether the destructor is
<code class="sourceCode default">noexcept</code> <a href="#fn2" class="footnote-ref" id="fnref2" role="doc-noteref"><sup>2</sup></a>.
Because
<code class="sourceCode default">std::is_nothrow_convertible</code> is
specified in terms of
<code class="sourceCode default">std::is_convertible</code>, a change to
the current semantics of
<code class="sourceCode default">std::is_nothrow_convertible</code>
could obviate the need for <span class="citation" data-cites="LWG4028">[<a href="#ref-LWG4028" role="doc-biblioref">LWG4028</a>]</span> or necessitate a different
specification mechanism. I am, therefore, not proposing adopting this
approach at this time.</p>
<p>The third approach also suffers from similar interactions with
<code class="sourceCode default">std::is_nothrow_convertible</code>. In
addition, expressing
<code class="sourceCode default">std::is_convertible</code> in terms of
the existence of an implicit conversion sequence (as defined by §
<span>12.2.4.2.1
<a href="https://wg21.link/N4971#over.best.ics.general">[over.best.ics.general]</a></span>)
would subject the library to the unresolved issue described by <span class="citation" data-cites="CWG2525">[<a href="#ref-CWG2525" role="doc-biblioref">CWG2525</a>]</span>.</p>
<p>Therefore, revision 1 of this paper proposed the first approach.
Pursuant to the EWG’s feedback in Varna (June, 2023), the carve-out was
moved to core wording in revision 2. The carve-out was removed in
revision 3 after CWG review in Kona (November, 2023), and has now been
restored following discussion on the LWG reflector.</p>
<h1 data-number="7" id="implementation-experience"><span class="header-section-number">7</span> Implementation experience<a href="#implementation-experience" class="self-link"></a></h1>
<p>I have built a patched version of Clang 16.0.6 that implements the
change proposed in this paper. Using the patched Clang, I successfully
built Clang itself, which contains an estimated 3.7 million lines of C++
code in the <code class="sourceCode default">llvm</code> and
<code class="sourceCode default">clang</code> subdirectories of the
<code class="sourceCode default">llvm-project</code> repository (<span class="citation" data-cites="LLVM">[<a href="#ref-LLVM" role="doc-biblioref">LLVM</a>]</span>). There were 13 failed tests,
which can be divided into the following categories.</p>
<ul>
<li><strong>Tests that verify that Clang issues a warning for a return
statement that binds a returned reference to a temporary fail because
the warning is now an error</strong> — Each such test can be replaced by
a test that verifies the issuance of an error and, optionally, a test in
which the temporary is returned through an indirect path for which Clang
is still expected to issue a warning.</li>
<li><strong>Tests that verify that a function compiles to a particular
LLVM <!-- lah: why `llvm` elsewhere and LLVM here? --> bitcode sequence,
e.g., functions that return references to temporaries</strong> — If such
functions are made ill formed as this paper proposes, such tests can
simply be deleted.</li>
<li><strong>Tests that verify that Clang’s constant evaluator diagnoses
a read from a temporary whose lifetime has ended</strong> — These tests
can be amended so that the function that returns the reference does so
through an indirect path that does not trigger an error under this
paper’s proposed wording but should still cause the constant evaluation
to fail.</li>
<li><strong>Tests that use the return statement only to check that
binding a particular reference to a particular temporary is well
formed</strong> — These tests can be changed so that they bind a local
reference rather than a returned reference.</li>
</ul>
<p>I also successfully built Bloomberg’s BDE repository (<span class="citation" data-cites="BDE">[<a href="#ref-BDE" role="doc-biblioref">BDE</a>]</span>), including all tests (1.7 million
lines of C++ code) and Chromium (<span class="citation" data-cites="Chromium">[<a href="#ref-Chromium" role="doc-biblioref">Chromium</a>]</span>), comprising 39 million lines
of C++ code. These estimates were generated using David A. Wheeler’s
SLOCCount (<span class="citation" data-cites="SLOCCount">[<a href="#ref-SLOCCount" role="doc-biblioref">SLOCCount</a>]</span>). These
results suggest that the change proposed by this paper is unlikely to
cause many compilation errors in existing code that has already been
reviewed and successfully deployed.</p>
<h1 data-number="8" id="wording"><span class="header-section-number">8</span> Wording<a href="#wording" class="self-link"></a></h1>
<p>The proposed wording is relative to <span class="citation" data-cites="N4971">[<a href="#ref-N4971" role="doc-biblioref">N4971</a>]</span>.</p>
<p>Strike p6.11 in § [class.temporary]:</p>
<blockquote>
<ul>
<li><span class="rm" style="color: #bf0303"><del>The lifetime of a
temporary bound to the returned value in a function
<span><code class="sourceCode default">return</code></span> statement
(8.7.4) is not extended; the temporary is destroyed at the end of the
full-expression in the
<span><code class="sourceCode default">return</code></span>
statement.</del></span></li>
</ul>
</blockquote>
<p>Insert a new paragraph, 6, at the end of § [stmt.return]:</p>
<blockquote>
<div class="add" style="color: #006e28">
<p>In a function whose return type is a reference, other than an
invented function for
<code class="sourceCode default">std::is_convertible</code>
([meta.rel]), a <code class="sourceCode default">return</code> statement
that binds the returned reference to an object that is the result of a
temporary expression ([class.temporary]) is ill-formed.<br />
[<em>Example 2:</em></p>
<div class="sourceCode" id="cb5"><pre class="sourceCode default cpp"><code class="sourceCode default"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a>auto&amp;&amp; f1() {</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>    return 42;  // ill-formed</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>const double&amp; f2() {</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>    static int x = 42;</span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>    return x;   // ill-formed</span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a>auto&amp;&amp; id(auto&amp;&amp; r) {</span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a>    return static_cast&lt;decltype(r)&amp;&amp;&gt;(r);</span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a>auto&amp;&amp; f3() {</span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a>    return id(42);  // OK, but probably a bug</span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>— <em>end example</em>]</p>
</div>
</blockquote>
<p>(<em>Note:</em> <span class="citation" data-cites="CWG2826">[<a href="#ref-CWG2826" role="doc-biblioref">CWG2826</a>]</span> proposes to
define the term “temporary expression” used by the above wording.)</p>
<h1 data-number="9" id="bibliography"><span class="header-section-number">9</span> References<a href="#bibliography" class="self-link"></a></h1>
<div id="refs" class="references csl-bib-body hanging-indent" role="doc-bibliography">
<div id="ref-BDE" class="csl-entry" role="doc-biblioentry">
[BDE] <a href="https://github.com/bloomberg/bde"><div class="csl-block">https://github.com/bloomberg/bde</div></a>
</div>
<div id="ref-Chromium" class="csl-entry" role="doc-biblioentry">
[Chromium] <a href="https://www.chromium.org/Home/"><div class="csl-block">https://www.chromium.org/Home/</div></a>
</div>
<div id="ref-CWG1696" class="csl-entry" role="doc-biblioentry">
[CWG1696] Richard Smith. 2013-05-31. Temporary lifetime and non-static
data member initializers. <a href="https://wg21.link/cwg1696"><div class="csl-block">https://wg21.link/cwg1696</div></a>
</div>
<div id="ref-CWG2525" class="csl-entry" role="doc-biblioentry">
[CWG2525] Jim X. 2021-09-25. Incorrect definition of implicit conversion
sequence. <a href="https://wg21.link/cwg2525"><div class="csl-block">https://wg21.link/cwg2525</div></a>
</div>
<div id="ref-CWG2826" class="csl-entry" role="doc-biblioentry">
[CWG2826] Brian Bi. 2022-12-16. Missing definition of <span>“temporary
expression.”</span> <a href="https://cplusplus.github.io/CWG/issues/2826.html"><div class="csl-block">https://cplusplus.github.io/CWG/issues/2826.html</div></a>
</div>
<div id="ref-LLVM" class="csl-entry" role="doc-biblioentry">
[LLVM] <a href="https://github.com/llvm/llvm-project/"><div class="csl-block">https://github.com/llvm/llvm-project/</div></a>
</div>
<div id="ref-LWG3400" class="csl-entry" role="doc-biblioentry">
[LWG3400] Jiang An. 2020-02-10. Does
<code class="sourceCode default">is_nothrow_convertible</code> consider
destruction of the destination type? <a href="https://wg21.link/lwg3400"><div class="csl-block">https://wg21.link/lwg3400</div></a>
</div>
<div id="ref-LWG4028" class="csl-entry" role="doc-biblioentry">
[LWG4028] Jiang An. 2023-12-18.
<code class="sourceCode default">std::is_(nothrow_)convertible</code>
should be reworded to avoid dependence on the
<code class="sourceCode default">return</code> statement. <a href="https://wg21.link/lwg4028"><div class="csl-block">https://wg21.link/lwg4028</div></a>
</div>
<div id="ref-N4971" class="csl-entry" role="doc-biblioentry">
[N4971] Thomas Köppe. 2023-12-18. Working Draft, Programming Languages —
C++. <a href="https://wg21.link/n4971"><div class="csl-block">https://wg21.link/n4971</div></a>
</div>
<div id="ref-P0315R2" class="csl-entry" role="doc-biblioentry">
[P0315R2] Louis Dionne. 2017-06-18. Lambdas in unevaluated context. <a href="https://wg21.link/p0315r2"><div class="csl-block">https://wg21.link/p0315r2</div></a>
</div>
<div id="ref-SLOCCount" class="csl-entry" role="doc-biblioentry">
[SLOCCount] <a href="https://dwheeler.com/sloccount/"><div class="csl-block">https://dwheeler.com/sloccount/</div></a>
</div>
</div>
<section id="footnotes" class="footnotes footnotes-end-of-document" role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p>All citations to the Standard are to working draft N4971
unless otherwise specified.<a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn2"><p>Revision 3 of this paper made the erroneous claim that
the LWG was considering making <code class="sourceCode default">std::is_convertible&lt;From, To&gt;</code> be
<code class="sourceCode default">true</code> when the type
<code class="sourceCode default">To</code> is not destructible. In fact,
changes are being contemplated to the behavior of only
<code class="sourceCode default">std::is_nothrow_convertible</code> (and
its <code class="sourceCode default">constructible</code>
counterpart).<a href="#fnref2" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>
</div>
</div>
</body>
</html>
