Topic: Request for comments: D1155 "More implicit moves


Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date: Sun, 12 Aug 2018 18:24:02 -0700 (PDT)
Raw View
------=_Part_1267_1623685081.1534123442452
Content-Type: multipart/alternative;
 boundary="----=_Part_1268_1389561066.1534123442452"

------=_Part_1268_1389561066.1534123442452
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Attached please find the current draft of my proposal D1155 "More implicit=
=20
moves."

Programmers expect return x; to trigger copy elision; or, at worst, to *imp=
licitly=20
> move* from x instead of copying. Occasionally, C++ violates their=20
> expectations and performs an expensive copy anyway. Based on our experien=
ce=20
> using Clang to diagnose unexpected copies in Chromium, Mozilla, and=20
> LibreOffice, we propose to change the standard so that these copies will =
be=20
> replaced with *implicit moves*.
> [...]
> This feature has effectively already been implemented in Clang since=20
> February 2018; see [D43322] <https://reviews.llvm.org/D43322>. Under the=
=20
> diagnostic option -Wreturn-std-move (which is enabled as part of -Wmove,=
=20
> -Wmost, and -Wall), the compiler performs overload resolution according=
=20
> to *both* rules =E2=80=94 the standard rule and also the rule proposed in=
 this=20
> proposal. If the two resolutions produce different results, then Clang=20
> emits a warning diagnostic explaining that the return value will not be=
=20
> implicitly moved and suggesting that the programmer add an explicit=20
> std::move.


This proposal is directly related to one of my CppCon 2018 talks: "RVO is=
=20
Harder Than It Looks=20
<https://cppcon2018.sched.com/event/FnL2/rvo-is-harder-than-it-looks-the-st=
ory-of-wreturn-std-move>
.."

I'd appreciate any feedback that anyone has on the paper in its current=20
state!  (And many thanks to Lukas Bergdoll for his excellent feedback=20
already.)

=E2=80=93Arthur

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/7fbf6b10-1ad6-4072-89fd-ac1e7dbfd406%40isocpp.or=
g.

------=_Part_1268_1389561066.1534123442452
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Attached please find the current draft of my proposal D115=
5 &quot;More implicit moves.&quot;<div><br><blockquote class=3D"gmail_quote=
" style=3D"margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-s=
tyle: solid; border-left-color: rgb(204, 204, 204); padding-left: 1ex;"><sp=
an style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-family: sa=
ns-serif; font-size: medium; orphans: 2; widows: 2;">Programmers expect=C2=
=A0</span><code class=3D"highlight" style=3D"caret-color: rgb(0, 0, 0); col=
or: rgb(0, 0, 0); font-family: Menlo, Consolas, &quot;DejaVu Sans Mono&quot=
;, Monaco, monospace; font-size: 0.9em; break-inside: avoid; padding: 0.1em=
; border-top-left-radius: 0.3em; border-top-right-radius: 0.3em; border-bot=
tom-right-radius: 0.3em; border-bottom-left-radius: 0.3em; background-color=
: rgb(245, 242, 240); orphans: 2; widows: 2;"><c- k=3D"" style=3D"color: rg=
b(153, 0, 85);">return</c->=C2=A0<c- n=3D"" style=3D"color: rgb(0, 119, 170=
);">x</c-><c- p=3D"" style=3D"color: rgb(153, 153, 153);">;</c-></code><spa=
n style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-family: san=
s-serif; font-size: medium; orphans: 2; widows: 2;">=C2=A0to trigger copy e=
lision; or, at worst, to=C2=A0</span><i style=3D"caret-color: rgb(0, 0, 0);=
 color: rgb(0, 0, 0); font-family: sans-serif; orphans: 2; widows: 2;">impl=
icitly move</i><span style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0=
); font-family: sans-serif; font-size: medium; orphans: 2; widows: 2;">=C2=
=A0from=C2=A0</span><code class=3D"highlight" style=3D"caret-color: rgb(0, =
0, 0); color: rgb(0, 0, 0); font-family: Menlo, Consolas, &quot;DejaVu Sans=
 Mono&quot;, Monaco, monospace; font-size: 0.9em; break-inside: avoid; padd=
ing: 0.1em; border-top-left-radius: 0.3em; border-top-right-radius: 0.3em; =
border-bottom-right-radius: 0.3em; border-bottom-left-radius: 0.3em; backgr=
ound-color: rgb(245, 242, 240); orphans: 2; widows: 2;"><c- n=3D"" style=3D=
"color: rgb(0, 119, 170);">x</c-></code><span style=3D"caret-color: rgb(0, =
0, 0); color: rgb(0, 0, 0); font-family: sans-serif; font-size: medium; orp=
hans: 2; widows: 2;">=C2=A0instead of copying. Occasionally, C++ violates t=
heir expectations and performs an expensive copy anyway. Based on our exper=
ience using Clang to diagnose unexpected copies in Chromium, Mozilla, and L=
ibreOffice, we propose to change the standard so that these copies will be =
replaced with=C2=A0</span><i style=3D"caret-color: rgb(0, 0, 0); color: rgb=
(0, 0, 0); font-family: sans-serif; orphans: 2; widows: 2;">implicit moves<=
/i><span style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-fami=
ly: sans-serif; font-size: medium; orphans: 2; widows: 2;">.</span><span st=
yle=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-family: sans-se=
rif; font-size: medium; orphans: 2; widows: 2;"><br></span>[...]<br><span s=
tyle=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-family: sans-s=
erif; font-size: medium; orphans: 2; widows: 2;">This feature has effective=
ly already been implemented in Clang since February 2018; see=C2=A0</span><=
a data-link-type=3D"biblio" href=3D"https://reviews.llvm.org/D43322" style=
=3D"white-space: pre; color: rgb(3, 69, 117); border-bottom-width: 1px; bor=
der-bottom-style: solid; border-bottom-color: rgb(187, 187, 187); padding-r=
ight: 1px; padding-left: 1px; margin-right: -1px; margin-left: -1px; font-f=
amily: sans-serif; orphans: 2; widows: 2;">[D43322]</a><span style=3D"caret=
-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-family: sans-serif; font-si=
ze: medium; orphans: 2; widows: 2;">. Under the diagnostic option=C2=A0</sp=
an><code class=3D"highlight" style=3D"caret-color: rgb(0, 0, 0); color: rgb=
(0, 0, 0); font-family: Menlo, Consolas, &quot;DejaVu Sans Mono&quot;, Mona=
co, monospace; font-size: 0.9em; break-inside: avoid; padding: 0.1em; borde=
r-top-left-radius: 0.3em; border-top-right-radius: 0.3em; border-bottom-rig=
ht-radius: 0.3em; border-bottom-left-radius: 0.3em; background-color: rgb(2=
45, 242, 240); orphans: 2; widows: 2;"><c- o=3D"" style=3D"color: rgb(153, =
153, 153);">-</c-><c- n=3D"" style=3D"color: rgb(0, 119, 170);">Wreturn</c-=
><c- o=3D"" style=3D"color: rgb(153, 153, 153);">-</c-><c- n=3D"" style=3D"=
color: rgb(0, 119, 170);">std</c-><c- o=3D"" style=3D"color: rgb(153, 153, =
153);">-</c-><c- n=3D"" style=3D"color: rgb(0, 119, 170);">move</c-></code>=
<span style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-family:=
 sans-serif; font-size: medium; orphans: 2; widows: 2;">=C2=A0(which is ena=
bled as part of=C2=A0</span><code class=3D"highlight" style=3D"caret-color:=
 rgb(0, 0, 0); color: rgb(0, 0, 0); font-family: Menlo, Consolas, &quot;Dej=
aVu Sans Mono&quot;, Monaco, monospace; font-size: 0.9em; break-inside: avo=
id; padding: 0.1em; border-top-left-radius: 0.3em; border-top-right-radius:=
 0.3em; border-bottom-right-radius: 0.3em; border-bottom-left-radius: 0.3em=
; background-color: rgb(245, 242, 240); orphans: 2; widows: 2;"><c- o=3D"" =
style=3D"color: rgb(153, 153, 153);">-</c-><c- n=3D"" style=3D"color: rgb(0=
, 119, 170);">Wmove</c-></code><span style=3D"caret-color: rgb(0, 0, 0); co=
lor: rgb(0, 0, 0); font-family: sans-serif; font-size: medium; orphans: 2; =
widows: 2;">,=C2=A0</span><code class=3D"highlight" style=3D"caret-color: r=
gb(0, 0, 0); color: rgb(0, 0, 0); font-family: Menlo, Consolas, &quot;DejaV=
u Sans Mono&quot;, Monaco, monospace; font-size: 0.9em; break-inside: avoid=
; padding: 0.1em; border-top-left-radius: 0.3em; border-top-right-radius: 0=
..3em; border-bottom-right-radius: 0.3em; border-bottom-left-radius: 0.3em; =
background-color: rgb(245, 242, 240); orphans: 2; widows: 2;"><c- o=3D"" st=
yle=3D"color: rgb(153, 153, 153);">-</c-><c- n=3D"" style=3D"color: rgb(0, =
119, 170);">Wmost</c-></code><span style=3D"caret-color: rgb(0, 0, 0); colo=
r: rgb(0, 0, 0); font-family: sans-serif; font-size: medium; orphans: 2; wi=
dows: 2;">, and=C2=A0</span><code class=3D"highlight" style=3D"caret-color:=
 rgb(0, 0, 0); color: rgb(0, 0, 0); font-family: Menlo, Consolas, &quot;Dej=
aVu Sans Mono&quot;, Monaco, monospace; font-size: 0.9em; break-inside: avo=
id; padding: 0.1em; border-top-left-radius: 0.3em; border-top-right-radius:=
 0.3em; border-bottom-right-radius: 0.3em; border-bottom-left-radius: 0.3em=
; background-color: rgb(245, 242, 240); orphans: 2; widows: 2;"><c- o=3D"" =
style=3D"color: rgb(153, 153, 153);">-</c-><c- n=3D"" style=3D"color: rgb(0=
, 119, 170);">Wall</c-></code><span style=3D"caret-color: rgb(0, 0, 0); col=
or: rgb(0, 0, 0); font-family: sans-serif; font-size: medium; orphans: 2; w=
idows: 2;">), the compiler performs overload resolution according to=C2=A0<=
/span><em style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-fam=
ily: sans-serif; orphans: 2; widows: 2;">both</em><span style=3D"caret-colo=
r: rgb(0, 0, 0); color: rgb(0, 0, 0); font-family: sans-serif; font-size: m=
edium; orphans: 2; widows: 2;">=C2=A0rules =E2=80=94 the standard rule and =
also the rule proposed in this proposal. If the two resolutions produce dif=
ferent results, then Clang emits a warning diagnostic explaining that the r=
eturn value will not be implicitly moved and suggesting that the programmer=
 add an explicit=C2=A0</span><code class=3D"highlight" style=3D"caret-color=
: rgb(0, 0, 0); color: rgb(0, 0, 0); font-family: Menlo, Consolas, &quot;De=
jaVu Sans Mono&quot;, Monaco, monospace; font-size: 0.9em; break-inside: av=
oid; padding: 0.1em; border-top-left-radius: 0.3em; border-top-right-radius=
: 0.3em; border-bottom-right-radius: 0.3em; border-bottom-left-radius: 0.3e=
m; background-color: rgb(245, 242, 240); orphans: 2; widows: 2;"><c- n=3D""=
 style=3D"color: rgb(0, 119, 170);">std</c-><c- o=3D"" style=3D"color: rgb(=
153, 153, 153);">::</c-><c- n=3D"" style=3D"color: rgb(0, 119, 170);">move<=
/c-></code><span style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); f=
ont-family: sans-serif; font-size: medium; orphans: 2; widows: 2;">.</span>=
</blockquote></div><div><span style=3D"caret-color: rgb(0, 0, 0); color: rg=
b(0, 0, 0); font-family: sans-serif; font-size: medium; orphans: 2; widows:=
 2;"><br></span></div><div><span style=3D"caret-color: rgb(0, 0, 0); color:=
 rgb(0, 0, 0); orphans: 2; widows: 2;"><font face=3D"arial, sans-serif" siz=
e=3D"2">This proposal is directly related to one of my CppCon 2018 talks: &=
quot;<a href=3D"https://cppcon2018.sched.com/event/FnL2/rvo-is-harder-than-=
it-looks-the-story-of-wreturn-std-move">RVO is Harder Than It Looks</a>.&qu=
ot;</font></span></div><div><span style=3D"caret-color: rgb(0, 0, 0); color=
: rgb(0, 0, 0); orphans: 2; widows: 2;"><font face=3D"arial, sans-serif" si=
ze=3D"2"><br></font></span></div><div><span style=3D"caret-color: rgb(0, 0,=
 0); color: rgb(0, 0, 0); orphans: 2; widows: 2;"><font face=3D"arial, sans=
-serif" size=3D"2">I&#39;d appreciate any feedback that anyone has on the p=
aper in its current state! =C2=A0(And many thanks to Lukas Bergdoll for his=
 excellent feedback already.)</font></span></div><div><span style=3D"caret-=
color: rgb(0, 0, 0); color: rgb(0, 0, 0); orphans: 2; widows: 2;"><font fac=
e=3D"arial, sans-serif" size=3D"2"><br></font></span></div><div><span style=
=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); orphans: 2; widows: 2;"=
><font face=3D"arial, sans-serif" size=3D"2">=E2=80=93Arthur</font></span><=
/div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/7fbf6b10-1ad6-4072-89fd-ac1e7dbfd406%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/7fbf6b10-1ad6-4072-89fd-ac1e7dbfd406=
%40isocpp.org</a>.<br />

------=_Part_1268_1389561066.1534123442452--

------=_Part_1267_1623685081.1534123442452
Content-Type: text/html; charset=UTF-8;
 name=more-implicit-moves-draft-4.html
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment; filename=more-implicit-moves-draft-4.html
X-Attachment-Id: 0f317b5d-2765-47a8-bf5d-d8a7078978e4
Content-ID: <0f317b5d-2765-47a8-bf5d-d8a7078978e4>

<!doctype html><html lang=3D"en">
 <head>
  <meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type">
  <meta content=3D"width=3Ddevice-width, initial-scale=3D1, shrink-to-fit=
=3Dno" name=3D"viewport">
  <title>D1155R0: More implicit moves</title>
<style data-fill-with=3D"stylesheet">/*************************************=
*****************************************
 *                   Style sheet for the W3C specifications                =
   *
 *
 * Special classes handled by this style sheet include:
 *
 * Indices
 *   - .toc for the Table of Contents (<ol class=3D"toc">)
 *     + <span class=3D"secno"> for the section numbers
 *   - #toc for the Table of Contents (<nav id=3D"toc">)
 *   - ul.index for Indices (<a href=3D"#ref">term</a><span>, in =C2=A7N.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=3D'complex data'> for extra-complex tables
 *     -> use <td class=3D'long'> for paragraph-length cell content
 *     -> use <td class=3D'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=3D'secn=
o'>3.2</span>)
 *   - .marker for source-inserted example/figure/issue numbers (<span clas=
s=3D'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 possi=
ble.
 *   - js-added ToC jump links (see fixup.js)
 *
 **************************************************************************=
****/

/**************************************************************************=
****/
/*                                   Body                                  =
   */
/**************************************************************************=
****/

=09body {
=09=09counter-reset: example figure issue;

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

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

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


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

/** Header ****************************************************************=
****/

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

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

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

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

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

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

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

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

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

/** Copyright *************************************************************=
****/

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

/**************************************************************************=
****/
/*                                Sectioning                               =
   */
/**************************************************************************=
****/

/** Headings **************************************************************=
****/

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

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

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

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

/** Subheadings ***********************************************************=
****/

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

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

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

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

=09p {
=09=09margin: 1em 0;
=09}

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

/**************************************************************************=
****/
/*                                    Code                                 =
   */
/**************************************************************************=
****/

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

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

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

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

  /* Do something nice. */

/**************************************************************************=
****/
/*                                    Links                                =
   */
/**************************************************************************=
****/

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

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

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

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

/**************************************************************************=
****/
/*                                    Images                               =
   */
/**************************************************************************=
****/

=09img {
=09=09border-style: none;
=09}

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

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

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

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

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

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

/** Blockquotes ***********************************************************=
****/

=09blockquote {
=09=09border-color: silver;
=09}

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

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

/** Example ***************************************************************=
****/

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

/**************************************************************************=
****/
/*                                    Tables                               =
   */
/**************************************************************************=
****/

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


/*
Alternate table alignment rules

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

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

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

Possible extra rowspan handling

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

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

/**************************************************************************=
****/
/*                                  Indices                                =
   */
/**************************************************************************=
****/


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

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

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

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

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

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

=09=09.toc li {
=09=09=09clear: both;
=09=09}

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

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

=09@supports (display:grid) {
=09=09/* Use #toc over .toc to override non-@supports rules. */
=09=09#toc {
=09=09=09display: grid;
=09=09=09align-content: start;
=09=09=09grid-template-columns: auto 1fr;
=09=09=09grid-column-gap: 1rem;
=09=09=09column-gap: 1rem;
=09=09=09grid-row-gap: .6rem;
=09=09=09row-gap: .6rem;
=09=09}
=09=09#toc h2 {
=09=09=09grid-column: 1 / -1;
=09=09=09margin-bottom: 0;
=09=09}
=09=09#toc ol,
=09=09#toc li,
=09=09#toc a {
=09=09=09display: contents;
=09=09=09/* Switch <a> to subgrid when supported */
=09=09}
=09=09#toc span {
=09=09=09margin: 0;
=09=09}
=09=09#toc > .toc > li > a > span {
=09=09=09/* The spans of the top-level list,
=09=09=09   comprising the first items of each top-level section. */
=09=09=09margin-top: 1.1rem;
=09=09}
=09=09#toc#toc .secno { /* Ugh, need more specificity to override base.css =
*/
=09=09=09grid-column: 1;
=09=09=09width: auto;
=09=09=09margin-left: 0;
=09=09}
=09=09#toc .content {
=09=09=09grid-column: 2;
=09=09=09width: auto;
=09=09=09margin-right: 1rem;
=09=09}
=09=09#toc .content:hover {
=09=09=09background: rgba(75%, 75%, 75%, .25);
=09=09=09border-bottom: 3px solid #054572;
=09=09=09margin-bottom: -3px;
=09=09}
=09=09#toc li li li .content {
=09=09=09margin-left: 1rem;
=09=09}
=09=09#toc li li li li .content {
=09=09=09margin-left: 2rem;
=09=09}
=09}


/** Index *****************************************************************=
****/

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

/** Index Tables *****************************************************/
=09/* See also the data table styling section, which this effectively subcl=
asses */

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

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

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

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

/**************************************************************************=
****/
/*                                    Print                                =
   */
/**************************************************************************=
****/

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

/**************************************************************************=
****/
/*                                    Legacy                               =
   */
/**************************************************************************=
****/

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



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

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

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

=09@media not print {
=09=09.overlarge {
=09=09=09overflow-x: auto;
=09=09=09/* See Lea Verou's explanation background-attachment:
=09=09=09 * http://lea.verou.me/2012/04/background-attachment-local/
=09=09=09 *
=09=09=09background: top left  / 4em 100% linear-gradient(to right,  #fffff=
f, rgba(255, 255, 255, 0)) local,
=09=09=09            top right / 4em 100% linear-gradient(to left, #ffffff,=
 rgba(255, 255, 255, 0)) local,
=09=09=09            top left  / 1em 100% linear-gradient(to right,  #c3c3c=
5, rgba(195, 195, 197, 0)) scroll,
=09=09=09            top right / 1em 100% linear-gradient(to left, #c3c3c5,=
 rgba(195, 195, 197, 0)) scroll,
=09=09=09            white;
=09=09=09background-repeat: no-repeat;
=09=09=09*/
=09=09}
=09}
</style>
<style type=3D"text/css">
    table, th, td {
      border: 1px solid black;
      border-collapse: collapse;
      vertical-align: top;
    }
    th, td {
      border-left: none;
      border-right: none;
      padding: 0px 10px;
    }
    th {
      text-align: center;
    }
  </style>
  <meta content=3D"Bikeshed version ca499dee738ad325bae89163f1eee6d8a2978cf=
4" name=3D"generator">
  <link href=3D"https://isocpp.org/favicon.ico" rel=3D"icon">
<style>
ins  {background-color: #CCFFCC; text-decoration: underline;}
del  {background-color: #FFCACA; text-decoration: line-through;}
</style>
<style>/* style-md-lists */

/* This is a weird hack for me not yet following the commonmark spec
   regarding paragraph and lists. */
[data-md] > :first-child {
    margin-top: 0;
}
[data-md] > :last-child {
    margin-bottom: 0;
}</style>
<style>/* style-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: "=C2=B6"; }
..heading > a.self-link::before { content: "=C2=A7"; }
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: "=E2=80=98";
}
..css::after, .property::after, .descriptor::after {
    content: "=E2=80=99";
}
..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=3D"property"]::before,
[data-link-type=3D"propdesc"]::before,
[data-link-type=3D"descriptor"]::before,
[data-link-type=3D"value"]::before,
[data-link-type=3D"function"]::before,
[data-link-type=3D"at-rule"]::before,
[data-link-type=3D"selector"]::before,
[data-link-type=3D"maybe"]::before {
    content: "=E2=80=98";
}
[data-link-type=3D"property"]::after,
[data-link-type=3D"propdesc"]::after,
[data-link-type=3D"descriptor"]::after,
[data-link-type=3D"value"]::after,
[data-link-type=3D"function"]::after,
[data-link-type=3D"at-rule"]::after,
[data-link-type=3D"selector"]::after,
[data-link-type=3D"maybe"]::after {
    content: "=E2=80=99";
}

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

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

[data-link-type=3Dbiblio] {
    white-space: pre;
}</style>
 <body class=3D"h-entry">
  <div class=3D"head">
   <p data-fill-with=3D"logo"></p>
   <h1 class=3D"p-name no-ref" id=3D"title">D1155R0<br>More implicit moves<=
/h1>
   <h2 class=3D"no-num no-toc no-ref heading settled" id=3D"subtitle"><span=
 class=3D"content">Draft Proposal, <time class=3D"dt-updated" datetime=3D"2=
018-08-11">2018-08-11</time></span></h2>
   <div data-fill-with=3D"spec-metadata">
    <dl>
     <dt>Author:
     <dd>
      <dd class=3D"editor p-author h-card vcard"><a class=3D"p-name fn u-em=
ail email" href=3D"mailto:arthur.j.odwyer@gmail.com">Arthur O'Dwyer</a>
     <dt>Audience:
     <dd>EWG
     <dt>Project:
     <dd>ISO/IEC JTC1/SC22/WG21 14882: Programming Language =E2=80=94 C++
     <dt>Draft Revision:
     <dd>4
     <dt>Current Source:
     <dd><a href=3D"https://github.com/Quuxplusone/draft/blob/gh-pages/d115=
5-more-implicit-moves.bs">github.com/Quuxplusone/draft/blob/gh-pages/d1155-=
more-implicit-moves.bs</a>
     <dt>Current:
     <dd><a href=3D"https://rawgit.com/Quuxplusone/draft/gh-pages/d1155-mor=
e-implicit-moves.html">rawgit.com/Quuxplusone/draft/gh-pages/d1155-more-imp=
licit-moves.html</a>
    </dl>
   </div>
   <div data-fill-with=3D"warning"></div>
   <hr title=3D"Separator for header">
  </div>
  <div class=3D"p-summary" data-fill-with=3D"abstract">
   <h2 class=3D"no-num no-toc no-ref heading settled" id=3D"abstract"><span=
 class=3D"content">Abstract</span></h2>
   <p>Programmers expect <code class=3D"highlight"><c- k>return</c-> <c- n>=
x</c-><c- p>;</c-></code> to trigger copy elision; or, at worst, to <i>impl=
icitly move</i> from <code class=3D"highlight"><c- n>x</c-></code> instead =
of copying. Occasionally, C++ violates their expectations and performs
an expensive copy anyway.
Based on our experience using Clang to diagnose unexpected copies in Chromi=
um, Mozilla,
and LibreOffice, we propose to change the standard so that these copies wil=
l be replaced with <i>implicit moves</i>.</p>
  </div>
  <nav data-fill-with=3D"table-of-contents" id=3D"toc">
   <h2 class=3D"no-num no-toc no-ref" id=3D"contents">Table of Contents</h2=
>
   <ol class=3D"toc" role=3D"directory">
    <li>
     <a href=3D"#background"><span class=3D"secno">1</span> <span class=3D"=
content">Background</span></a>
     <ol class=3D"toc">
      <li><a href=3D"#slicing"><span class=3D"secno">1.1</span> <span class=
=3D"content">Slicing is pessimized</span></a>
      <li><a href=3D"#conversion"><span class=3D"secno">1.2</span> <span cl=
ass=3D"content">Non-constructor conversion is pessimized</span></a>
      <li><a href=3D"#throwing"><span class=3D"secno">1.3</span> <span clas=
s=3D"content">Throwing is pessimized</span></a>
     </ol>
    <li><a href=3D"#wording"><span class=3D"secno">2</span> <span class=3D"=
content">Proposed wording</span></a>
    <li>
     <a href=3D"#implementation"><span class=3D"secno">3</span> <span class=
=3D"content">Implementation experience</span></a>
     <ol class=3D"toc">
      <li><a href=3D"#true-positives"><span class=3D"secno">3.1</span> <spa=
n class=3D"content">Plenitude of true positives</span></a>
      <li><a href=3D"#false-positives"><span class=3D"secno">3.2</span> <sp=
an class=3D"content">Lack of false positives</span></a>
     </ol>
    <li><a href=3D"#acknowledgments"><span class=3D"secno">4</span> <span c=
lass=3D"content">Acknowledgments</span></a>
    <li>
     <a href=3D"#references"><span class=3D"secno"></span> <span class=3D"c=
ontent">References</span></a>
     <ol class=3D"toc">
      <li><a href=3D"#informative"><span class=3D"secno"></span> <span clas=
s=3D"content">Informative References</span></a>
     </ol>
   </ol>
  </nav>
  <main>
   <h2 class=3D"heading settled" data-level=3D"1" id=3D"background"><span c=
lass=3D"secno">1. </span><span class=3D"content">Background</span><a class=
=3D"self-link" href=3D"#background"></a></h2>
   <p>Each version of C++ has improved the efficiency of returning objects =
by value. By the middle of the last
decade, copy elision was reliable (if not technically guaranteed) in situat=
ions like this:</p>
<pre class=3D"language-c++ highlight"><c- n>Widget</c-> <c- nf>one</c-><c- =
p>()</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>Widget</c-><c- p>();</c->  <c- c1>// copy elisi=
on</c->
<c- p>}</c->
<c- n>Widget</c-> <c- nf>two</c-><c- p>()</c-> <c- p>{</c->
    <c- n>Widget</c-> <c- n>result</c-><c- p>;</c->
    <c- k>return</c-> <c- n>result</c-><c- p>;</c->  <c- c1>// copy elision=
</c->
<c- p>}</c->
</pre>
   <p>In C++11, a completely new feature was added: a change to overload re=
solution which I will call <em>implicit move</em>. Even when copy elision i=
s impossible, the compiler is sometimes
required to <em>implicitly move</em> the <code class=3D"highlight"><c- k>re=
turn</c-></code> statement=E2=80=99s operand into the result object:</p>
<pre class=3D"language-c++ highlight"><c- n>std</c-><c- o>::</c-><c- n>shar=
ed_ptr</c-><c- o>&lt;</c-><c- n>Base</c-><c- o>></c-> <c- n>three</c-><c- p=
>()</c-> <c- p>{</c->
    <c- n>std</c-><c- o>::</c-><c- n>shared_ptr</c-><c- o>&lt;</c-><c- n>Ba=
se</c-><c- o>></c-> <c- n>result</c-><c- p>;</c->
    <c- k>return</c-> <c- n>result</c-><c- p>;</c->  <c- c1>// copy elision=
</c->
<c- p>}</c->
<c- n>std</c-><c- o>::</c-><c- n>shared_ptr</c-><c- o>&lt;</c-><c- n>Base</=
c-><c- o>></c-> <c- n>four</c-><c- p>()</c-> <c- p>{</c->
    <c- n>std</c-><c- o>::</c-><c- n>shared_ptr</c-><c- o>&lt;</c-><c- n>De=
rived</c-><c- o>></c-> <c- n>result</c-><c- p>;</c->
    <c- k>return</c-> <c- n>result</c-><c- p>;</c->  <c- c1>// no copy elis=
ion, but implicitly moved (not copied)</c->
<c- p>}</c->
</pre>
   <p>The wording for this optimization was amended by <a data-link-type=3D=
"biblio" href=3D"#biblio-cwg1579">[CWG1579]</a>. The current wording in <a =
href=3D"http://eel.is/c++draft/class.copy.elision#3">[class.copy.elision]/3=
</a> says:</p>
   <blockquote>
    <p>In the following copy-initialization contexts, a move operation migh=
t be used instead of a copy operation:</p>
    <ul>
     <li data-md>
      <p>If the <em>expression</em> in a <code class=3D"highlight"><c- k>re=
turn</c-></code> statement is a (possibly parenthesized) <em>id-expression<=
/em> that
names an object with automatic storage duration declared in the body or <em=
>parameter-declaration-clause</em> of the innermost enclosing function or <=
em>lambda-expression</em>, or</p>
     <li data-md>
      <p>if the operand of a <em>throw-expression</em> is the name of a non=
-volatile automatic object
(other than a <b>function</b> or catch-clause parameter) whose scope does n=
ot extend beyond
the end of the innermost enclosing <em>try-block</em> (if there is one),</p=
>
    </ul>
    <p>overload resolution to select the constructor for the copy is first =
performed as if the object were
designated by an rvalue. If the first overload resolution fails or was not =
performed, or if the type
of the first parameter of the selected <b>constructor</b> is not an rvalue =
reference to <b>the object=E2=80=99s</b> type
(possibly cv-qualified), overload resolution is performed again, considerin=
g the object as an lvalue.</p>
   </blockquote>
   <p>The bolded phrases above indicate places where the wording diverges f=
rom a na=C3=AFve programmer=E2=80=99s intuition.
Consider the following <a href=3D"https://godbolt.org/g/poynjg">examples</a=
>...</p>
   <h3 class=3D"heading settled" data-level=3D"1.1" id=3D"slicing"><span cl=
ass=3D"secno">1.1. </span><span class=3D"content">Slicing is pessimized</sp=
an><a class=3D"self-link" href=3D"#slicing"></a></h3>
   <p>Slicing is pessimized because of the bolded phrase <b>the object=E2=
=80=99s</b>.</p>
<pre class=3D"language-c++ highlight"><c- n>std</c-><c- o>::</c-><c- n>shar=
ed_ptr</c-><c- o>&lt;</c-><c- n>Base</c-><c- o>></c-> <c- n>five</c-><c- p>=
()</c-> <c- p>{</c->
    <c- n>std</c-><c- o>::</c-><c- n>shared_ptr</c-><c- o>&lt;</c-><c- n>De=
rived</c-><c- o>></c-> <c- n>result</c-><c- p>;</c->
    <c- k>return</c-> <c- n>result</c-><c- p>;</c->  <c- c1>// no copy elis=
ion, but implicitly moved (never copied)</c->
<c- p>}</c->
<c- n>Base</c-> <c- n>six</c-><c- p>()</c-> <c- p>{</c->
    <c- n>Derived</c-> <c- n>result</c-><c- p>;</c->
    <c- k>return</c-> <c- n>result</c-><c- p>;</c->  <c- c1>// no copy elis=
ion, and no implicit move (the object is copied)</c->
<c- p>}</c->
</pre>
   <p class=3D"note" role=3D"note"><span>Note:</span> The comment in <code =
class=3D"highlight"><c- n>six</c-></code> matches the current Standard word=
ing, and matches Clang=E2=80=99s behavior.
GCC=E2=80=99s behavior <em>already</em>, since GCC 8.1, is to do the implic=
it move.</p>
   <h3 class=3D"heading settled" data-level=3D"1.2" id=3D"conversion"><span=
 class=3D"secno">1.2. </span><span class=3D"content">Non-constructor conver=
sion is pessimized</span><a class=3D"self-link" href=3D"#conversion"></a></=
h3>
   <p>Non-constructor conversion is pessimized because of the bolded phrase=
 <b>constructor</b>.</p>
<pre class=3D"language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c-=
 n>class</c-> <c- n>T</c-><c- o>></c->
<c- k>struct</c-> <c- n>Red</c-> <c- p>{</c->
    <c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>U</c-><c- o>><=
/c-> <c- n>Red</c-><c- p>(</c-><c- k>const</c-> <c- n>Red</c-><c- o>&lt;</c=
-><c- n>U</c-><c- o>></c-> <c- o>&amp;</c-><c- p>);</c->
    <c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>U</c-><c- o>><=
/c-> <c- n>Red</c-><c- p>(</c-><c- n>Red</c-><c- o>&lt;</c-><c- n>U</c-><c-=
 o>>&amp;&amp;</c-><c- p>);</c->
<c- p>};</c->

<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>T</c-><c- o>></c->
<c- k>struct</c-> <c- n>Blue</c-> <c- p>{</c->
    <c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>U</c-><c- o>><=
/c-> <c- n>operator</c-> <c- n>Blue</c-><c- o>&lt;</c-><c- n>U</c-><c- o>><=
/c-><c- p>()</c-> <c- k>const</c-> <c- o>&amp;</c-><c- p>;</c->
    <c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>U</c-><c- o>><=
/c-> <c- n>operator</c-> <c- n>Blue</c-><c- o>&lt;</c-><c- n>U</c-><c- o>><=
/c-><c- p>()</c-> <c- o>&amp;&amp;</c-><c- p>;</c->
<c- p>};</c->

<c- n>Red</c-><c- o>&lt;</c-><c- n>Base</c-><c- o>></c-> <c- n>seven</c-><c=
- p>()</c-> <c- p>{</c->
    <c- n>Red</c-><c- o>&lt;</c-><c- n>Derived</c-><c- o>></c-> <c- n>w</c-=
><c- p>;</c->
    <c- k>return</c-> <c- n>w</c-><c- p>;</c->  <c- c1>// no copy elision, =
but implicitly moved (never copied)</c->
<c- p>}</c->
<c- n>Blue</c-><c- o>&lt;</c-><c- n>Base</c-><c- o>></c-> <c- n>eight</c-><=
c- p>()</c-> <c- p>{</c->
    <c- n>Blue</c-><c- o>&lt;</c-><c- n>Derived</c-><c- o>></c-> <c- n>w</c=
-><c- p>;</c->
    <c- k>return</c-> <c- n>w</c-><c- p>;</c->  <c- c1>// no copy elision, =
and no implicit move (the object is copied)</c->
<c- p>}</c->
</pre>
   <h3 class=3D"heading settled" data-level=3D"1.3" id=3D"throwing"><span c=
lass=3D"secno">1.3. </span><span class=3D"content">Throwing is pessimized</=
span><a class=3D"self-link" href=3D"#throwing"></a></h3>
   <p>Throwing is pessimized because of the bolded phrase <b>function</b> [=
parameter].</p>
<pre class=3D"language-c++ highlight"><c- b>void</c-> <c- nf>nine</c-><c- p=
>()</c-> <c- p>{</c->
    <c- n>Widget</c-> <c- n>w</c-><c- p>;</c->
    <c- n>throw</c-> <c- n>w</c-><c- p>;</c->  <c- c1>// non-guaranteed cop=
y elision, but implicitly moved (never copied)</c->
<c- p>}</c->
<c- n>Widget</c-> <c- nf>ten</c-><c- p>(</c-><c- n>Widget</c-> <c- n>w</c->=
<c- p>)</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>w</c-><c- p>;</c->  <c- c1>// no copy elision, =
but implicitly moved (never copied)</c->
<c- p>}</c->
<c- b>void</c-> <c- nf>eleven</c-><c- p>(</c-><c- n>Widget</c-> <c- n>w</c-=
><c- p>)</c-> <c- p>{</c->
    <c- n>throw</c-> <c- n>w</c-><c- p>;</c->  <c- c1>// no copy elision, a=
nd no implicit move (the object is copied)</c->
<c- p>}</c->
</pre>
   <p class=3D"note" role=3D"note"><span>Note:</span> The comment in <code =
class=3D"highlight"><c- n>eleven</c-></code> matches the current Standard w=
ording, and matches GCC=E2=80=99s behavior.
Clang=E2=80=99s behavior <em>already</em>, since Clang 4.0.1 or earlier, is=
 to do the implicit move.</p>
   <p>We propose to remove all three of these unnecessary limitations.</p>
   <h2 class=3D"heading settled" data-level=3D"2" id=3D"wording"><span clas=
s=3D"secno">2. </span><span class=3D"content">Proposed wording</span><a cla=
ss=3D"self-link" href=3D"#wording"></a></h2>
   <p>Modify <a href=3D"http://eel.is/c++draft/class.copy.elision#3">[class=
..copy.elision]/3</a> as follows:</p>
   <blockquote>
    <p>In the following copy-initialization contexts, a move operation migh=
t be used instead of a copy operation:</p>
    <ul>
     <li data-md>
      <p>If the <em>expression</em> in a <code class=3D"highlight"><c- k>re=
turn</c-></code> statement is a (possibly parenthesized) <em>id-expression<=
/em> that
names an object with automatic storage duration declared in the body or <em=
>parameter-declaration-clause</em> of the innermost enclosing function or <=
em>lambda-expression</em>, or</p>
     <li data-md>
      <p>
       if the operand of a <em>throw-expression</em> is the name of a non-v=
olatile automatic object
(other than a=20
       <del>function or</del>
        catch-clause parameter) whose scope does not extend beyond
the end of the innermost enclosing <em>try-block</em> (if there is one),
      </p>
    </ul>
    <p>
     overload resolution to select the constructor for the copy is first pe=
rformed as if the object were
designated by an rvalue. If the first overload resolution fails or was not =
performed,=20
     <del>or if the type
of the first parameter of the selected constructor is not an rvalue referen=
ce to the object=E2=80=99s type
(possibly cv-qualified),</del>
      overload resolution is performed again, considering the object as an =
lvalue.
[<em>Note:</em> This two-stage overload resolution must be performed regard=
less of whether copy elision will occur.
It determines the constructor to be called if elision is not performed, and=
 the selected constructor
must be accessible even if the call is elided. =E2=80=94<em>end note</em>]
    </p>
   </blockquote>
   <p class=3D"note" role=3D"note"><span>Note:</span> I believe that the tw=
o instances of the word "constructor" in the quoted note remain correct. Th=
ey
refer to the constructor selected to initialize the result object, as the v=
ery last step of the conversion
sequence. This proposed change merely permits the conversion sequence to be=
 longer than a single step; for
example, it might involve a derived-to-base conversion followed by a move-c=
onstructor, or a user-defined
conversion operator followed by a move-constructor. In either case, as far =
as the quoted note is concerned,
that ultimate move-constructor is the "constructor to be called," and indee=
d it must be accessible
even if elision is performed.</p>
   <h2 class=3D"heading settled" data-level=3D"3" id=3D"implementation"><sp=
an class=3D"secno">3. </span><span class=3D"content">Implementation experie=
nce</span><a class=3D"self-link" href=3D"#implementation"></a></h2>
   <p>This feature has effectively already been implemented in Clang since =
February 2018; see <a data-link-type=3D"biblio" href=3D"#biblio-d43322">[D4=
3322]</a>.
Under the diagnostic option <code class=3D"highlight"><c- o>-</c-><c- n>Wre=
turn</c-><c- o>-</c-><c- n>std</c-><c- o>-</c-><c- n>move</c-></code> (whic=
h is enabled as part of <code class=3D"highlight"><c- o>-</c-><c- n>Wmove</=
c-></code>, <code class=3D"highlight"><c- o>-</c-><c- n>Wmost</c-></code>, =
and <code class=3D"highlight"><c- o>-</c-><c- n>Wall</c-></code>),
the compiler performs overload resolution according to <em>both</em> rules =
=E2=80=94 the standard rule and also
the rule proposed in this proposal. If the two resolutions produce differen=
t results, then Clang
emits a warning diagnostic explaining that the return value will not be imp=
licitly moved and
suggesting that the programmer add an explicit <code class=3D"highlight"><c=
- n>std</c-><c- o>::</c-><c- n>move</c-></code>.</p>
   <h3 class=3D"heading settled" data-level=3D"3.1" id=3D"true-positives"><=
span class=3D"secno">3.1. </span><span class=3D"content">Plenitude of true =
positives</span><a class=3D"self-link" href=3D"#true-positives"></a></h3>
   <p>These warning diagnostics have proven helpful on real code.
Many instances have been reported of code that is currently accidentally pe=
ssimized,
and which would become optimized (with no loss of correctness) if this prop=
osal were adopted:</p>
   <ul>
    <li data-md>
     <p><a data-link-type=3D"biblio" href=3D"#biblio-sg14">[SG14]</a>: a cl=
ever trick to reduce code duplication by using conversion operators,
rather than converting constructors, turned out to cause unnecessary copyin=
g in a common use-case.</p>
    <li data-md>
     <p><a data-link-type=3D"biblio" href=3D"#biblio-chromium">[Chromium]</=
a>: a non-standard container library used <code class=3D"highlight"><c- n>i=
terator</c-><c- o>::</c-><c- k>operator</c-> <c- n>const_iterator</c-><c- p=
>()</c-> <c- o>&amp;&amp;</c-></code> instead of <code class=3D"highlight">=
<c- n>const_iterator</c-><c- o>::</c-><c- n>const_iterator</c-><c- p>(</c->=
<c- n>iterator</c-><c- o>&amp;&amp;</c-><c- p>)</c-></code>.
(The actual committed diff is <a href=3D"https://chromium-review.googlesour=
ce.com/c/chromium/src/+/1025435">here</a>.)</p>
    <li data-md>
     <p><a data-link-type=3D"biblio" href=3D"#biblio-libreoffice">[LibreOff=
ice]</a>: "An explicit std::move would be needed in the return statements, =
as there=E2=80=99s a
conversion from <code class=3D"highlight"><c- n>VclPtrInstance</c-></code> =
to base class <code class=3D"highlight"><c- n>VclPtr</c-></code> involved."=
</p>
   </ul>
   <p>However, we must note that about half of the true positives from the =
diagnostic are on code
like the following example, which is not affected by this proposal:</p>
<pre class=3D"language-c++ highlight"><c- n>std</c-><c- o>::</c-><c- n>stri=
ng</c-> <c- n>twelve</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>strin=
g</c-><c- o>&amp;&amp;</c-> <c- n>s</c-><c- p>)</c-> <c- p>{</c->
    <c- n>s</c-> <c- o>+=3D</c-> <c- s>"foo"</c-><c- p>;</c->
    <c- k>return</c-> <c- n>s</c-><c- p>;</c->  <c- c1>// no copy elision, =
and no implicit move (the object is copied)</c->
<c- p>}</c->
</pre>
   <p>See <a data-link-type=3D"biblio" href=3D"#biblio-khronos">[Khronos]</=
a>, <a data-link-type=3D"biblio" href=3D"#biblio-folly">[Folly]</a>, and th=
ree of the four diffs in <a data-link-type=3D"biblio" href=3D"#biblio-chrom=
ium">[Chromium]</a>.
Some number of programmers certainly expect a move here.
However, we believe that the rule "references are never implicitly moved-fr=
om" is teachable, and there
is no need to meddle with it for C++20. In these cases, we are happy to exp=
lain that the programmer
should either add <code class=3D"highlight"><c- n>std</c-><c- o>::</c-><c- =
n>move</c-></code> or stop passing by rvalue-reference in the first place.<=
/p>
   <p><a data-link-type=3D"biblio" href=3D"#biblio-aws">[AWS]</a> is a part=
icularly egregious variation. (The committed diff is <a href=3D"https://git=
hub.com/aws/aws-sdk-cpp/commit/ded84836cd7bf15aa2375a6c1f7143f34d985df1#dif=
f-2ce19b694bb11d0ff1676f740d32f98dL136">here</a>.)</p>
<pre class=3D"language-c++ highlight"><c- n>std</c-><c- o>::</c-><c- n>stri=
ng</c-> <c- n>thirteen</c-><c- p>()</c-> <c- p>{</c->
    <c- n>std</c-><c- o>::</c-><c- n>string</c-><c- o>&amp;&amp;</c-> <c- n=
>s</c-> <c- o>=3D</c-> <c- s>"hello world"</c-><c- p>;</c->
    <c- k>return</c-> <c- n>s</c-><c- p>;</c->  <c- c1>// no copy elision, =
and no implicit move (the object is copied)</c->
<c- p>}</c->
</pre>
   <h3 class=3D"heading settled" data-level=3D"3.2" id=3D"false-positives">=
<span class=3D"secno">3.2. </span><span class=3D"content">Lack of false pos=
itives</span><a class=3D"self-link" href=3D"#false-positives"></a></h3>
   <p>In five months we have received a single "false positive" report (<a =
data-link-type=3D"biblio" href=3D"#biblio-mozilla">[Mozilla]</a>), which co=
mplained that the move-constructor suggested
by Clang was <em>not significantly more efficient</em> than the actually se=
lected copy-constructor. The programmer preferred not
to add the suggested <code class=3D"highlight"><c- n>std</c-><c- o>::</c-><=
c- n>move</c-></code> because the code ugliness was not worth the minor per=
formance gain.
This proposal would give Mozilla that minor performance gain without the ug=
liness =E2=80=94 the best of both worlds!</p>
   <p>We have never received any bug report that any move-constructor sugge=
sted by Clang would have been incorrect.</p>
   <h2 class=3D"heading settled" data-level=3D"4" id=3D"acknowledgments"><s=
pan class=3D"secno">4. </span><span class=3D"content">Acknowledgments</span=
><a class=3D"self-link" href=3D"#acknowledgments"></a></h2>
   <p>Thanks to Lukas Bergdoll for his copious feedback on drafts of this p=
roposal.</p>
  </main>
<script>
(function() {
  "use strict";
  var collapseSidebarText =3D '<span aria-hidden=3D"true">=E2=86=90</span> =
'
                          + '<span>Collapse Sidebar</span>';
  var expandSidebarText   =3D '<span aria-hidden=3D"true">=E2=86=92</span> =
'
                          + '<span>Pop Out Sidebar</span>';
  var tocJumpText         =3D '<span aria-hidden=3D"true">=E2=86=91</span> =
'
                          + '<span>Jump to Table of Contents</span>';

  var sidebarMedia =3D window.matchMedia('screen and (min-width: 78em)');
  var autoToggle   =3D function(e){ toggleSidebar(e.matches) };
  if(sidebarMedia.addListener) {
    sidebarMedia.addListener(autoToggle);
  }

  function toggleSidebar(on) {
    if (on =3D=3D undefined) {
      on =3D !document.body.classList.contains('toc-sidebar');
    }

    /* Don=E2=80=99t scroll to compensate for the ToC if we=E2=80=99re abov=
e it already. */
    var headY =3D 0;
    var head =3D document.querySelector('.head');
    if (head) {
      // terrible approx of "top of ToC"
      headY +=3D head.offsetTop + head.offsetHeight;
    }
    var skipScroll =3D window.scrollY < headY;

    var toggle =3D document.getElementById('toc-toggle');
    var tocNav =3D document.getElementById('toc');
    if (on) {
      var tocHeight =3D tocNav.offsetHeight;
      document.body.classList.add('toc-sidebar');
      document.body.classList.remove('toc-inline');
      toggle.innerHTML =3D collapseSidebarText;
      if (!skipScroll) {
        window.scrollBy(0, 0 - tocHeight);
      }
      tocNav.focus();
      sidebarMedia.addListener(autoToggle); // auto-collapse when out of ro=
om
    }
    else {
      document.body.classList.add('toc-inline');
      document.body.classList.remove('toc-sidebar');
      toggle.innerHTML =3D expandSidebarText;
      if (!skipScroll) {
        window.scrollBy(0, tocNav.offsetHeight);
      }
      if (toggle.matches(':hover')) {
        /* Unfocus button when not using keyboard navigation,
           because I don=E2=80=99t know where else to send the focus. */
        toggle.blur();
      }
    }
  }

  function createSidebarToggle() {
    /* Create the sidebar toggle in JS; it shouldn=E2=80=99t exist when JS =
is off. */
    var toggle =3D document.createElement('a');
      /* This should probably be a button, but appearance isn=E2=80=99t sta=
ndards-track.*/
    toggle.id =3D 'toc-toggle';
    toggle.class =3D 'toc-toggle';
    toggle.href =3D '#toc';
    toggle.innerHTML =3D collapseSidebarText;

    sidebarMedia.addListener(autoToggle);
    var toggler =3D function(e) {
      e.preventDefault();
      sidebarMedia.removeListener(autoToggle); // persist explicit off stat=
es
      toggleSidebar();
      return false;
    }
    toggle.addEventListener('click', toggler, false);


    /* Get <nav id=3Dtoc-nav>, or make it if we don=E2=80=99t have one. */
    var tocNav =3D document.getElementById('toc-nav');
    if (!tocNav) {
      tocNav =3D document.createElement('p');
      tocNav.id =3D 'toc-nav';
      /* Prepend for better keyboard navigation */
      document.body.insertBefore(tocNav, document.body.firstChild);
    }
    /* While we=E2=80=99re at it, make sure we have a Jump to Toc link. */
    var tocJump =3D document.getElementById('toc-jump');
    if (!tocJump) {
      tocJump =3D document.createElement('a');
      tocJump.id =3D 'toc-jump';
      tocJump.href =3D '#toc';
      tocJump.innerHTML =3D tocJumpText;
      tocNav.appendChild(tocJump);
    }

    tocNav.appendChild(toggle);
  }

  var toc =3D 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() =3D=3D "a" && document.body.classLi=
st.contains('toc-sidebar') && !sidebarMedia.matches) {
        toggleSidebar(false);
      }
    }, false);
  }
  else {
    console.warn("Can=E2=80=99t find Table of Contents. Please use <nav id=
=3D'toc'> around the ToC.");
  }

  /* Wrap tables in case they overflow */
  var tables =3D document.querySelectorAll(':not(.overlarge) > table.data, =
:not(.overlarge) > table.index');
  var numTables =3D tables.length;
  for (var i =3D 0; i < numTables; i++) {
    var table =3D tables[i];
    var wrapper =3D document.createElement('div');
    wrapper.className =3D 'overlarge';
    table.parentNode.insertBefore(wrapper, table);
    wrapper.appendChild(table);
  }

})();
</script>
  <h2 class=3D"no-num no-ref heading settled" id=3D"references"><span class=
=3D"content">References</span><a class=3D"self-link" href=3D"#references"><=
/a></h2>
  <h3 class=3D"no-num no-ref heading settled" id=3D"informative"><span clas=
s=3D"content">Informative References</span><a class=3D"self-link" href=3D"#=
informative"></a></h3>
  <dl>
   <dt id=3D"biblio-aws">[AWS]
   <dd><a href=3D"https://github.com/aws/aws-sdk-cpp/issues/847">Use const =
references to extend lifetime of temporaries</a>. April 2018. URL: <a href=
=3D"https://github.com/aws/aws-sdk-cpp/issues/847">https://github.com/aws/a=
ws-sdk-cpp/issues/847</a>
   <dt id=3D"biblio-chromium">[Chromium]
   <dd><a href=3D"https://bugs.chromium.org/p/chromium/issues/detail?id=3D8=
32211">clean up and enable Wreturn-std-move</a>. April 2018. URL: <a href=
=3D"https://bugs.chromium.org/p/chromium/issues/detail?id=3D832211">https:/=
/bugs.chromium.org/p/chromium/issues/detail?id=3D832211</a>
   <dt id=3D"biblio-cwg1579">[CWG1579]
   <dd>Jeffrey Yasskin. <a href=3D"http://open-std.org/JTC1/SC22/WG21/docs/=
cwg_defects.html#1579">Return by converting move constructor</a>. October 2=
012. URL: <a href=3D"http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.ht=
ml#1579">http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#1579</a>
   <dt id=3D"biblio-d43322">[D43322]
   <dd>Arthur O'Dwyer. <a href=3D"https://reviews.llvm.org/D43322">Diagnose=
 cases of 'return x' that should be 'return std::move(x)' for efficiency</a=
>. February 2018. URL: <a href=3D"https://reviews.llvm.org/D43322">https://=
reviews.llvm.org/D43322</a>
   <dt id=3D"biblio-folly">[Folly]
   <dd><a href=3D"https://github.com/facebook/folly/commit/b5105fc5581eef1a=
f2a809b7a3a50ac820e572ae">fix -Wreturn-std-move errors</a>. April 2018. URL=
: <a href=3D"https://github.com/facebook/folly/commit/b5105fc5581eef1af2a80=
9b7a3a50ac820e572ae">https://github.com/facebook/folly/commit/b5105fc5581ee=
f1af2a809b7a3a50ac820e572ae</a>
   <dt id=3D"biblio-khronos">[Khronos]
   <dd><a href=3D"https://github.com/KhronosGroup/SPIRV-Tools/issues/1521">=
Use std::move(str) suggested with -Wreturn-std-move</a>. April 2018. URL: <=
a href=3D"https://github.com/KhronosGroup/SPIRV-Tools/issues/1521">https://=
github.com/KhronosGroup/SPIRV-Tools/issues/1521</a>
   <dt id=3D"biblio-libreoffice">[LibreOffice]
   <dd>Stephan Bergmann. <a href=3D"https://cgit.freedesktop.org/libreoffic=
e/core/commit/?id=3D74b6e61dde64c5e24bffacda6f67dbf3d1fc7032">-Werror,-Wret=
urn-std-move (recent Clang trunk)</a>. April 2018. URL: <a href=3D"https://=
cgit.freedesktop.org/libreoffice/core/commit/?id=3D74b6e61dde64c5e24bffacda=
6f67dbf3d1fc7032">https://cgit.freedesktop.org/libreoffice/core/commit/?id=
=3D74b6e61dde64c5e24bffacda6f67dbf3d1fc7032</a>
   <dt id=3D"biblio-mozilla">[Mozilla]
   <dd><a href=3D"https://bugzilla.mozilla.org/show_bug.cgi?id=3D1454848">V=
arious '-Wreturn-std-move' build warnings with clang 7.0 (trunk), for cases=
 where return invokes (cheap) string copy-constructor rather than move cons=
tructor</a>. April 2018. URL: <a href=3D"https://bugzilla.mozilla.org/show_=
bug.cgi?id=3D1454848">https://bugzilla.mozilla.org/show_bug.cgi?id=3D145484=
8</a>
   <dt id=3D"biblio-sg14">[SG14]
   <dd>Arthur O'Dwyer. <a href=3D"https://github.com/WG21-SG14/SG14/issues/=
125">inplace_function implicit conversion chooses copy over move</a>. Febru=
ary 2018. URL: <a href=3D"https://github.com/WG21-SG14/SG14/issues/125">htt=
ps://github.com/WG21-SG14/SG14/issues/125</a>
  </dl>
------=_Part_1267_1623685081.1534123442452--

.


Author: Barry Revzin <barry.revzin@gmail.com>
Date: Tue, 14 Aug 2018 15:57:50 -0700 (PDT)
Raw View
------=_Part_2133_1320469648.1534287470584
Content-Type: text/plain; charset="UTF-8"

I dunno why my messages keep getting deleted.

Anyway, attempt #3. The slicing example is not compelling and should go last, if it even needs to be present at all. Much more compelling are by-value sink arguments:

struct A {
  A(std::string);
};

struct B {
  B(std::unique_ptr<int>);
};

A eleven() {
  std::string s;
  return s; // copy
}

B twelve() {
  std::unique_ptr<int> p;
  return p; // error
}

Would be nice if those both compiled and moved. Also, would be worth it to ping Howard about the original restriction... it's from way back in N1952.

Also, as a formatting note... would suggest highlighting instead of bold. The bold doesn't really stand out.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/b2f16fed-730b-402c-bffb-eb4dc8f3ed69%40isocpp.org.

------=_Part_2133_1320469648.1534287470584--

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Wed, 15 Aug 2018 02:09:04 +0300
Raw View
On 15 August 2018 at 01:57, Barry Revzin <barry.revzin@gmail.com> wrote:
> I dunno why my messages keep getting deleted.
>
> Anyway, attempt #3. The slicing example is not compelling and should go last, if it even needs to be present at all. Much more compelling are by-value sink arguments:
>
> struct A {
>   A(std::string);
> };
>
> struct B {
>   B(std::unique_ptr<int>);
> };
>
> A eleven() {
>   std::string s;
>   return s; // copy
> }
>
> B twelve() {
>   std::unique_ptr<int> p;
>   return p; // error
> }
>
> Would be nice if those both compiled and moved. Also, would be worth it to ping Howard about the original restriction... it's from way back in N1952.
>
> Also, as a formatting note... would suggest highlighting instead of bold. The bold doesn't really stand out.

This paper http://open-std.org/JTC1/SC22/WG21/docs/papers/2017/p0527r0.html
is already in Core.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAFk2RUbfpNn-WAX96K6D%2BiHYJEzum%2BYsMzTFh6cX-MdtD%2BW1uA%40mail.gmail.com.

.


Author: Barry Revzin <barry.revzin@gmail.com>
Date: Tue, 14 Aug 2018 18:14:52 -0500
Raw View
--0000000000005d3fd105736d61d3
Content-Type: text/plain; charset="UTF-8"

On Tue, Aug 14, 2018, 6:09 PM Ville Voutilainen <ville.voutilainen@gmail.com>
wrote:

> On 15 August 2018 at 01:57, Barry Revzin <barry.revzin@gmail.com> wrote:
> > I dunno why my messages keep getting deleted.
> >
> > Anyway, attempt #3. The slicing example is not compelling and should go
> last, if it even needs to be present at all. Much more compelling are
> by-value sink arguments:
> >
> > struct A {
> >   A(std::string);
> > };
> >
> > struct B {
> >   B(std::unique_ptr<int>);
> > };
> >
> > A eleven() {
> >   std::string s;
> >   return s; // copy
> > }
> >
> > B twelve() {
> >   std::unique_ptr<int> p;
> >   return p; // error
> > }
> >
> > Would be nice if those both compiled and moved. Also, would be worth it
> to ping Howard about the original restriction... it's from way back in
> N1952.
> >
> > Also, as a formatting note... would suggest highlighting instead of
> bold. The bold doesn't really stand out.
>
> This paper
> http://open-std.org/JTC1/SC22/WG21/docs/papers/2017/p0527r0.html
> is already in Core.
>

That paper seems orthogonal to this one. It doesn't address any of the
examples here, as far as I can tell?

>

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CACS8nvd32j1WEuDr16%3Dq5gD06XoR68a8qM-48Pk4CZC3mXVz5A%40mail.gmail.com.

--0000000000005d3fd105736d61d3
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"auto"><div><br><br><div class=3D"gmail_quote"><div dir=3D"ltr">=
On Tue, Aug 14, 2018, 6:09 PM Ville Voutilainen &lt;<a href=3D"mailto:ville=
..voutilainen@gmail.com">ville.voutilainen@gmail.com</a>&gt; wrote:<br></div=
><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1=
px #ccc solid;padding-left:1ex">On 15 August 2018 at 01:57, Barry Revzin &l=
t;<a href=3D"mailto:barry.revzin@gmail.com" target=3D"_blank" rel=3D"norefe=
rrer">barry.revzin@gmail.com</a>&gt; wrote:<br>
&gt; I dunno why my messages keep getting deleted.<br>
&gt;<br>
&gt; Anyway, attempt #3. The slicing example is not compelling and should g=
o last, if it even needs to be present at all. Much more compelling are by-=
value sink arguments:<br>
&gt;<br>
&gt; struct A {<br>
&gt;=C2=A0 =C2=A0A(std::string);<br>
&gt; };<br>
&gt;<br>
&gt; struct B {<br>
&gt;=C2=A0 =C2=A0B(std::unique_ptr&lt;int&gt;);<br>
&gt; };<br>
&gt;<br>
&gt; A eleven() {<br>
&gt;=C2=A0 =C2=A0std::string s;<br>
&gt;=C2=A0 =C2=A0return s; // copy<br>
&gt; }<br>
&gt;<br>
&gt; B twelve() {<br>
&gt;=C2=A0 =C2=A0std::unique_ptr&lt;int&gt; p;<br>
&gt;=C2=A0 =C2=A0return p; // error<br>
&gt; }<br>
&gt;<br>
&gt; Would be nice if those both compiled and moved. Also, would be worth i=
t to ping Howard about the original restriction... it&#39;s from way back i=
n N1952.<br>
&gt;<br>
&gt; Also, as a formatting note... would suggest highlighting instead of bo=
ld. The bold doesn&#39;t really stand out.<br>
<br>
This paper <a href=3D"http://open-std.org/JTC1/SC22/WG21/docs/papers/2017/p=
0527r0.html" rel=3D"noreferrer noreferrer" target=3D"_blank">http://open-st=
d.org/JTC1/SC22/WG21/docs/papers/2017/p0527r0.html</a><br>
is already in Core.<br></blockquote></div></div><div dir=3D"auto"><br></div=
><div dir=3D"auto">That paper seems orthogonal to this one. It doesn&#39;t =
address any of the examples here, as far as I can tell?</div><div dir=3D"au=
to"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"m=
argin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
</blockquote></div></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CACS8nvd32j1WEuDr16%3Dq5gD06XoR68a8qM=
-48Pk4CZC3mXVz5A%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CACS8nvd32j1WEu=
Dr16%3Dq5gD06XoR68a8qM-48Pk4CZC3mXVz5A%40mail.gmail.com</a>.<br />

--0000000000005d3fd105736d61d3--

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Wed, 15 Aug 2018 02:22:00 +0300
Raw View
On 15 August 2018 at 02:14, Barry Revzin <barry.revzin@gmail.com> wrote:
>> This paper
>> http://open-std.org/JTC1/SC22/WG21/docs/papers/2017/p0527r0.html
>> is already in Core.
>
>
> That paper seems orthogonal to this one. It doesn't address any of the
> examples here, as far as I can tell?

Right; it's in the same problem space somewhat, but not quite the same.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAFk2RUbL2arV5B8AVpW64TMPCupfBi92zUZ0uhEuDjVx5XnB3Q%40mail.gmail.com.

.


Author: Howard Hinnant <howard.hinnant@gmail.com>
Date: Tue, 14 Aug 2018 20:34:43 -0400
Raw View
--Apple-Mail=_FCE6485E-6D21-4CBB-82D5-8CA657B04A0F
Content-Type: text/plain; charset="UTF-8"

This is CWG 1579:  http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1579

and was accepted for C++14.

Howard

On Aug 14, 2018, at 6:57 PM, Barry Revzin <barry.revzin@gmail.com> wrote:
>
> I dunno why my messages keep getting deleted.
>
> Anyway, attempt #3. The slicing example is not compelling and should go last, if it even needs to be present at all. Much more compelling are by-value sink arguments:
>
> struct A {
>  A(std::string);
> };
>
> struct B {
>  B(std::unique_ptr<int>);
> };
>
> A eleven() {
>  std::string s;
>  return s; // copy
> }
>
> B twelve() {
>  std::unique_ptr<int> p;
>  return p; // error
> }
>
> Would be nice if those both compiled and moved. Also, would be worth it to ping Howard about the original restriction... it's from way back in N1952.
>
> Also, as a formatting note... would suggest highlighting instead of bold. The bold doesn't really stand out.
>
> --
> You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/b2f16fed-730b-402c-bffb-eb4dc8f3ed69%40isocpp.org.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/98C0A9E1-E6BB-4E21-BA9A-A88FD45E9440%40gmail.com.

--Apple-Mail=_FCE6485E-6D21-4CBB-82D5-8CA657B04A0F
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename=signature.asc
Content-Type: application/pgp-signature;
 name=signature.asc
Content-Description: Message signed with OpenPGP

-----BEGIN PGP SIGNATURE-----

iQIzBAEBCAAdFiEEfIiFcJYbP97+HbHHZtwcLEqqFYIFAltzdSMACgkQZtwcLEqq
FYKDVw//UNnWUIdmzFSoYc23xIjFPqbjqzTB43a1c5hPAtNWqkIFJmXJIqPHlP7w
vdQnI5hAcoJFpRh28OyBU4LkeEss/VXN5fAQIcYYOgMSz+XcHqAtiuFADdaCWTMe
vTYc5n/CUlaoeIxFoJYdsCZZuk+bK1e6hlf376vigPxDI23BCv5Fb3aDDKX3rf7A
8AdrU67cxXrD+PGHmKAJdYkHwasrlZUYnZO0gwDuWjt7v7ZvCceUJAAF2m83feDG
NTHUEhneBKDHWlvzWygTNbRoqimxCtSnk17dUUEHqzDE2Iuh3zTXOYOhZb3W6OvV
WxwvUKWnNsdq7YFJqi8S3DCbhDhMUt0B5Lm7PBiBvEOD743NZ1NVsWKfHYLgalNN
hUsTeqtoZ0v+PTDNAWRJZT3oYh/j5/+mrJR2TGkQc5A/yv9kRUNuq38neQhn/r+W
Ia9gbww1k30loi6Q0uZZ+FgwSNHNyEz5LfN7oorSh469u+muHSfNmyfFd0oIIVZX
PMpFL3HfRk4wKb1Dxepi7RPSeGPP8B8t9QFuuJ9ighFW2267/iI63Ml9fFCsSExD
oVEqrjvvLTyQoKL6XEIC7mw5K4KEU9y9Zcs80baJJgTfGWWYeP1PyckBAElwxlWA
fImfpfedpXUCRQZRan0oFSNgFwAw0F76uFUJSqAPJ3AxUnlti/c=
=zjBm
-----END PGP SIGNATURE-----

--Apple-Mail=_FCE6485E-6D21-4CBB-82D5-8CA657B04A0F--

.


Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Tue, 14 Aug 2018 18:00:41 -0700
Raw View
--0000000000000a0ba205736edbb6
Content-Type: text/plain; charset="UTF-8"

No, Barry's right. Both of his examples (try to) make copies instead of
moving.
https://godbolt.org/g/uYgt7R

And I need to investigate why `-Wreturn-std-move` isn't triggering on that
first example!

However, re "slicing isn't motivating": slicing was actually my original
motivation for `-Wreturn-std-move` (and thus for the paper). My employer's
codebase relies heavily on value-semantics plus inheritance plus RAII, like
a `ListExpr` that is derived from `Expr` but has the same behavior w.r.t.
ownership of the underlying resource. So slicing a `ListExpr` into a plain
old `Expr` in a return statement is actually very common in our codebase.
Come to my CppCon talk
<https://cppcon2018.sched.com/event/FnL2/rvo-is-harder-than-it-looks-the-story-of-wreturn-std-move>
for more details! :)


On Tue, Aug 14, 2018 at 5:34 PM, Howard Hinnant <howard.hinnant@gmail.com>
wrote:

> This is CWG 1579:  http://www.open-std.org/jtc1/
> sc22/wg21/docs/cwg_defects.html#1579
>
> and was accepted for C++14.
>
> Howard
>
> On Aug 14, 2018, at 6:57 PM, Barry Revzin <barry.revzin@gmail.com> wrote:
> >
> > I dunno why my messages keep getting deleted.
> >
> > Anyway, attempt #3. The slicing example is not compelling and should go
> last, if it even needs to be present at all. Much more compelling are
> by-value sink arguments:
> >
> > struct A {
> >  A(std::string);
> > };
> >
> > struct B {
> >  B(std::unique_ptr<int>);
> > };
> >
> > A eleven() {
> >  std::string s;
> >  return s; // copy
> > }
> >
> > B twelve() {
> >  std::unique_ptr<int> p;
> >  return p; // error
> > }
> >
> > Would be nice if those both compiled and moved. Also, would be worth it
> to ping Howard about the original restriction... it's from way back in
> N1952.
> >
> > Also, as a formatting note... would suggest highlighting instead of
> bold. The bold doesn't really stand out.
> >
> > --
> > You received this message because you are subscribed to the Google
> Groups "ISO C++ Standard - Future Proposals" group.
> > To unsubscribe from this group and stop receiving emails from it, send
> an email to std-proposals+unsubscribe@isocpp.org.
> > To post to this group, send email to std-proposals@isocpp.org.
> > To view this discussion on the web visit https://groups.google.com/a/
> isocpp.org/d/msgid/std-proposals/b2f16fed-730b-402c-
> bffb-eb4dc8f3ed69%40isocpp.org.
>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this topic, visit https://groups.google.com/a/
> isocpp.org/d/topic/std-proposals/eeLS8vI05nM/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit https://groups.google.com/a/
> isocpp.org/d/msgid/std-proposals/98C0A9E1-E6BB-4E21-
> BA9A-A88FD45E9440%40gmail.com.
>

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADvuK0L%2BL3Qw01JqTD338unRD6aFdG97cgAt-swkqdbVeVWypw%40mail.gmail.com.

--0000000000000a0ba205736edbb6
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">No, Barry&#39;s right. Both of his examples (try to) make =
copies instead of moving.<div><a href=3D"https://godbolt.org/g/uYgt7R">http=
s://godbolt.org/g/uYgt7R</a><br></div><div><br></div><div>And I need to inv=
estigate why `-Wreturn-std-move` isn&#39;t triggering on that first example=
!</div><div><br></div><div>However, re &quot;slicing isn&#39;t motivating&q=
uot;: slicing was actually my original motivation for `-Wreturn-std-move` (=
and thus for the paper). My employer&#39;s codebase relies heavily on value=
-semantics plus inheritance plus RAII, like a `ListExpr` that is derived fr=
om `Expr` but has the same behavior w.r.t. ownership of the underlying reso=
urce. So slicing a `ListExpr` into a plain old `Expr` in a return statement=
 is actually very common in our codebase. Come to <a href=3D"https://cppcon=
2018.sched.com/event/FnL2/rvo-is-harder-than-it-looks-the-story-of-wreturn-=
std-move">my CppCon talk</a> for more details! :)</div><div><br></div></div=
><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">On Tue, Aug 14, =
2018 at 5:34 PM, Howard Hinnant <span dir=3D"ltr">&lt;<a href=3D"mailto:how=
ard.hinnant@gmail.com" target=3D"_blank">howard.hinnant@gmail.com</a>&gt;</=
span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8e=
x;border-left:1px #ccc solid;padding-left:1ex">This is CWG 1579:=C2=A0 <a h=
ref=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1579" r=
el=3D"noreferrer" target=3D"_blank">http://www.open-std.org/jtc1/<wbr>sc22/=
wg21/docs/cwg_defects.<wbr>html#1579</a><br>
<br>
and was accepted for C++14.<br>
<br>
Howard<br>
<span class=3D""><br>
On Aug 14, 2018, at 6:57 PM, Barry Revzin &lt;<a href=3D"mailto:barry.revzi=
n@gmail.com">barry.revzin@gmail.com</a>&gt; wrote:<br>
&gt; <br>
&gt; I dunno why my messages keep getting deleted.<br>
&gt; <br>
&gt; Anyway, attempt #3. The slicing example is not compelling and should g=
o last, if it even needs to be present at all. Much more compelling are by-=
value sink arguments:<br>
&gt; <br>
&gt; struct A {<br>
&gt;=C2=A0 A(std::string);<br>
&gt; };<br>
&gt; <br>
&gt; struct B {<br>
&gt;=C2=A0 B(std::unique_ptr&lt;int&gt;);<br>
&gt; };<br>
&gt; <br>
&gt; A eleven() {<br>
&gt;=C2=A0 std::string s;<br>
&gt;=C2=A0 return s; // copy<br>
&gt; }<br>
&gt; <br>
&gt; B twelve() {<br>
&gt;=C2=A0 std::unique_ptr&lt;int&gt; p;<br>
&gt;=C2=A0 return p; // error<br>
&gt; }<br>
&gt; <br>
&gt; Would be nice if those both compiled and moved. Also, would be worth i=
t to ping Howard about the original restriction... it&#39;s from way back i=
n N1952.<br>
&gt; <br>
&gt; Also, as a formatting note... would suggest highlighting instead of bo=
ld. The bold doesn&#39;t really stand out.<br>
&gt; <br>
&gt; --<br>
</span>&gt; You received this message because you are subscribed to the Goo=
gle Groups &quot;ISO C++ Standard - Future Proposals&quot; group.<br>
&gt; To unsubscribe from this group and stop receiving emails from it, send=
 an email to <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org">std-=
proposals+unsubscribe@<wbr>isocpp.org</a>.<br>
<span class=3D"">&gt; To post to this group, send email to <a href=3D"mailt=
o:std-proposals@isocpp.org">std-proposals@isocpp.org</a>.<br>
&gt; To view this discussion on the web visit <a href=3D"https://groups.goo=
gle.com/a/isocpp.org/d/msgid/std-proposals/b2f16fed-730b-402c-bffb-eb4dc8f3=
ed69%40isocpp.org" rel=3D"noreferrer" target=3D"_blank">https://groups.goog=
le.com/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/b2f16fed-730b-402c-<wbr=
>bffb-eb4dc8f3ed69%40isocpp.org</a><wbr>.<br>
<br>
-- <br>
You received this message because you are subscribed to a topic in the Goog=
le Groups &quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/eeLS8vI05nM/unsubscribe" rel=3D"noreferr=
er" target=3D"_blank">https://groups.google.com/a/<wbr>isocpp.org/d/topic/s=
td-<wbr>proposals/eeLS8vI05nM/<wbr>unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a href=
=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org">std-proposals+unsubscrib=
e@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br>
</span>To view this discussion on the web visit <a href=3D"https://groups.g=
oogle.com/a/isocpp.org/d/msgid/std-proposals/98C0A9E1-E6BB-4E21-BA9A-A88FD4=
5E9440%40gmail.com" rel=3D"noreferrer" target=3D"_blank">https://groups.goo=
gle.com/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/98C0A9E1-E6BB-4E21-<wb=
r>BA9A-A88FD45E9440%40gmail.com</a>.<br>
</blockquote></div><br></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CADvuK0L%2BL3Qw01JqTD338unRD6aFdG97cg=
At-swkqdbVeVWypw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADvuK0L%2BL3Qw=
01JqTD338unRD6aFdG97cgAt-swkqdbVeVWypw%40mail.gmail.com</a>.<br />

--0000000000000a0ba205736edbb6--

.


Author: Howard Hinnant <howard.hinnant@gmail.com>
Date: Tue, 14 Aug 2018 21:03:39 -0400
Raw View
--Apple-Mail=_1C0BC801-5A7B-4D21-AF40-A9F14E8B4852
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset="UTF-8"

I never claimed clang was conforming.  Try gcc.

Howard

On Aug 14, 2018, at 9:00 PM, Arthur O'Dwyer <arthur.j.odwyer@gmail.com> wro=
te:
>=20
> No, Barry's right. Both of his examples (try to) make copies instead of m=
oving.
> https://godbolt.org/g/uYgt7R
>=20
> And I need to investigate why `-Wreturn-std-move` isn't triggering on tha=
t first example!
>=20
> However, re "slicing isn't motivating": slicing was actually my original =
motivation for `-Wreturn-std-move` (and thus for the paper). My employer's =
codebase relies heavily on value-semantics plus inheritance plus RAII, like=
 a `ListExpr` that is derived from `Expr` but has the same behavior w.r.t. =
ownership of the underlying resource. So slicing a `ListExpr` into a plain =
old `Expr` in a return statement is actually very common in our codebase. C=
ome to my CppCon talk for more details! :)
>=20
>=20
> On Tue, Aug 14, 2018 at 5:34 PM, Howard Hinnant <howard.hinnant@gmail.com=
> wrote:
> This is CWG 1579:  http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defect=
s.html#1579
>=20
> and was accepted for C++14.
>=20
> Howard
>=20
> On Aug 14, 2018, at 6:57 PM, Barry Revzin <barry.revzin@gmail.com> wrote:
> >
> > I dunno why my messages keep getting deleted.
> >
> > Anyway, attempt #3. The slicing example is not compelling and should go=
 last, if it even needs to be present at all. Much more compelling are by-v=
alue sink arguments:
> >
> > struct A {
> >  A(std::string);
> > };
> >
> > struct B {
> >  B(std::unique_ptr<int>);
> > };
> >
> > A eleven() {
> >  std::string s;
> >  return s; // copy
> > }
> >
> > B twelve() {
> >  std::unique_ptr<int> p;
> >  return p; // error
> > }
> >
> > Would be nice if those both compiled and moved. Also, would be worth it=
 to ping Howard about the original restriction... it's from way back in N19=
52.
> >
> > Also, as a formatting note... would suggest highlighting instead of bol=
d. The bold doesn't really stand out.
> >
> > --
> > You received this message because you are subscribed to the Google Grou=
ps "ISO C++ Standard - Future Proposals" group.
> > To unsubscribe from this group and stop receiving emails from it, send =
an email to std-proposals+unsubscribe@isocpp.org.
> > To post to this group, send email to std-proposals@isocpp.org.
> > To view this discussion on the web visit https://groups.google.com/a/is=
ocpp.org/d/msgid/std-proposals/b2f16fed-730b-402c-bffb-eb4dc8f3ed69%40isocp=
p.org.
>=20
> --
> You received this message because you are subscribed to a topic in the Go=
ogle Groups "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this topic, visit https://groups.google.com/a/isocpp.=
org/d/topic/std-proposals/eeLS8vI05nM/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to std-p=
roposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit https://groups.google.com/a/isoc=
pp.org/d/msgid/std-proposals/98C0A9E1-E6BB-4E21-BA9A-A88FD45E9440%40gmail.c=
om.
>=20
>=20
> --
> You received this message because you are subscribed to the Google Groups=
 "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an=
 email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit https://groups.google.com/a/isoc=
pp.org/d/msgid/std-proposals/CADvuK0L%2BL3Qw01JqTD338unRD6aFdG97cgAt-swkqdb=
VeVWypw%40mail.gmail.com.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/596A9A4F-3F8E-430D-A218-F2CB7D90CBF0%40gmail.com=
..

--Apple-Mail=_1C0BC801-5A7B-4D21-AF40-A9F14E8B4852
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename=signature.asc
Content-Type: application/pgp-signature;
 name=signature.asc
Content-Description: Message signed with OpenPGP

-----BEGIN PGP SIGNATURE-----

iQIzBAEBCAAdFiEEfIiFcJYbP97+HbHHZtwcLEqqFYIFAltze+sACgkQZtwcLEqq
FYICXA//RO0d3Bfg//sjJZW0kbUWY5mc6V2tpQgw242zkzXkunXkARjEFThWudJS
Ttni/xpl8P9YemkAFhJFMuC5ya8/u6sZS/fH2Owi0HDtOzbArih7/sK7BqCofgzE
7SZWK5qeqrkllyj8R/M9+ZM1d/lxb3Yd7ambRHt+s5NCSVkCu35o7N/8vNkeMwMi
rj3gfGHsCtwerKkYht7XS92LJa1waHFExZpBlaesxjT9Qtc41buXG8mjRLmAOEA8
DA8cyx/3g3l5C0rKQ25nltaBWnAjifgB1wsMSsJ/4KW+pwvLot9pVFkZwkYPXx63
V3sTqsONu/SWqeTe24IVYwDvNpsf1xkQgwcH1FKNnHDWdbeNiRHJXlyC8l6tv/Hh
xDA6io/OhLBbwFnUeGfEPRzmPwAF1kdeOO4rWtpz7BJ+NkxG4aM3nf1Ce46px9oo
JaFhzLQtfE06m7+FGyIf9k7vNS8Bff5RHzWqJ1Two0PM2ZP4CzE102Izuoi72FmC
Ps2CO4Vfqh65HI6bgDA3uM+Tsd6yVAGiysz23dDwTNX4bn7sd3B7Fii1YtgzxPeO
HLNdHE7RLKz2br0Bde6fXv9ryxKvcXM1XyC0XnTc42KVCGGziRliWQp5SyPpZt48
7M1eIon8B3lLg5sZgLTFts1qd9Pczz94quDFqVy/Zd2c0YcxW3U=
=9QBa
-----END PGP SIGNATURE-----

--Apple-Mail=_1C0BC801-5A7B-4D21-AF40-A9F14E8B4852--

.


Author: Barry Revzin <barry.revzin@gmail.com>
Date: Tue, 14 Aug 2018 19:05:51 -0700 (PDT)
Raw View
------=_Part_2304_1691963630.1534298751902
Content-Type: multipart/alternative;
 boundary="----=_Part_2305_628422205.1534298751902"

------=_Part_2305_628422205.1534298751902
Content-Type: text/plain; charset="UTF-8"

On Tuesday, August 14, 2018 at 7:34:50 PM UTC-5, Howard Hinnant wrote:
>
> This is CWG 1579:
> http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1579
>
> and was accepted for C++14.
>
> Howard




I disagree. That issue allows for trying moves first for more cases, but it
still keeps the restriction (
http://eel.is/c++draft/class.copy.elision#3.sentence-2), emphasis mine:

> If the first overload resolution fails or was not performed, *or if the
type of the first parameter of the selected constructor is not an rvalue
reference to the object's type (possibly cv-qualified)*, overload
resolution is performed again, considering the object as an lvalue.
<http://eel.is/c++draft/class.copy.elision#3.sentence-2>

CWG 1579 allowed this case to become a move:

struct A {
  A(std::string&&);
};

A f() {
  std::string x;
  return x; // move because of this issue
}

but not either of the examples I mentioned.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/25a4f822-e9f3-47ce-9458-d3dd6b242421%40isocpp.org.

------=_Part_2305_628422205.1534298751902
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Tuesday, August 14, 2018 at 7:34:50 PM UTC-5, Howard Hi=
nnant wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">This is CWG 1579: =
=C2=A0<a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.ht=
ml#1579" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39=
;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22=
%2Fwg21%2Fdocs%2Fcwg_defects.html%231579\x26sa\x3dD\x26sntz\x3d1\x26usg\x3d=
AFQjCNHMCHN7BthJxYeTP2jFnOmsRI-VBA&#39;;return true;" onclick=3D"this.href=
=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1=
%2Fsc22%2Fwg21%2Fdocs%2Fcwg_defects.html%231579\x26sa\x3dD\x26sntz\x3d1\x26=
usg\x3dAFQjCNHMCHN7BthJxYeTP2jFnOmsRI-VBA&#39;;return true;">http://www.ope=
n-std.org/jtc1/<wbr>sc22/wg21/docs/cwg_defects.<wbr>html#1579</a>
<br>
<br>and was accepted for C++14.
<br>
<br>Howard=C2=A0</blockquote><blockquote class=3D"gmail_quote" style=3D"mar=
gin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">=
=C2=A0</blockquote><div><br></div><div class=3D"gmail_quote" style=3D"color=
: rgb(0, 0, 0); font-family: sans-serif; font-size: small;"><div>I disagree=
.. That issue allows for trying moves first for more cases, but it still kee=
ps the restriction (<a href=3D"http://eel.is/c++draft/class.copy.elision#3.=
sentence-2" style=3D"color: rgb(126, 87, 194); z-index: 0; position: relati=
ve;">http://eel.is/c++draft/class.copy.elision#3.sentence-2</a>), emphasis =
mine:</div><div><br></div>&gt; If the first overload resolution fails or wa=
s not performed, <b>or if the type of the first parameter of the selected c=
onstructor is not an rvalue reference to the object&#39;s type (possibly cv=
-qualified)</b>, overload resolution is performed again, considering the ob=
ject as an lvalue<a href=3D"http://eel.is/c++draft/class.copy.elision#3.sen=
tence-2" style=3D"color: rgb(126, 87, 194); z-index: 0; position: relative;=
">.</a></div><div class=3D"gmail_quote" style=3D"color: rgb(0, 0, 0); font-=
family: sans-serif; font-size: small;"><br></div><div><font color=3D"#00000=
0" face=3D"sans-serif" size=3D"2">CWG 1579 allowed this case to become a mo=
ve:</font></div><div><font color=3D"#000000" face=3D"sans-serif" size=3D"2"=
><br></font></div><div><font face=3D"sans-serif" size=3D"2"><div class=3D"p=
rettyprint" style=3D"background-color: rgb(250, 250, 250); border-color: rg=
b(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: break-=
word;"><code class=3D"prettyprint" style=3D""><div class=3D"subprettyprint"=
 style=3D""><span style=3D"color: #008;" class=3D"styled-by-prettify">struc=
t</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> A</span>=
<font color=3D"#666600"><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =
A</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify">std</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">string</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">&amp;&amp;);</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">};</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br><br>A f</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">()</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br>=C2=A0 std</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">::</span><span style=3D"color: #008;" class=3D"styled-by-prettify">str=
ing</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> x</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><span =
style=3D"color: #008;" class=3D"styled-by-prettify">return</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> x</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: #800;" class=
=3D"styled-by-prettify">// move because of this issue</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">}</span></font></div></code></div><br>=
but not either of the examples I mentioned.=C2=A0</font></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/25a4f822-e9f3-47ce-9458-d3dd6b242421%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/25a4f822-e9f3-47ce-9458-d3dd6b242421=
%40isocpp.org</a>.<br />

------=_Part_2305_628422205.1534298751902--

------=_Part_2304_1691963630.1534298751902--

.


Author: Howard Hinnant <howard.hinnant@gmail.com>
Date: Tue, 14 Aug 2018 22:35:17 -0400
Raw View
--Apple-Mail=_530CA5E9-1E56-481D-A8D1-4F0794EE8C36
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset="UTF-8"

Thank you for the education!  I had no idea the rules were this screwed up.

I was not strongly in favor, nor strongly against CWG 1579.  My rationale i=
s that the rules for implicit move should be easy to teach and remember.  Y=
ou have shown me that they are now far more cryptic than I understood them =
to be.  We would have been better off without CWG 1579 than in this half-wa=
y-there twisty maze of passages that all look alike.

    struct A
    {
        A(std::unique_ptr<int>) {}
    };

    struct B
    {
        B(std::unique_ptr<int>&&) {}
    };

    A
    test1()
    {
        std::unique_ptr<int> p;
        return p; // fails
    }

    B
    test2()
    {
        std::unique_ptr<int> p;
        return p; // ok
    }

Howard

On Aug 14, 2018, at 10:05 PM, Barry Revzin <barry.revzin@gmail.com> wrote:
>=20
> On Tuesday, August 14, 2018 at 7:34:50 PM UTC-5, Howard Hinnant wrote:
> This is CWG 1579:  http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defect=
s.html#1579
>=20
> and was accepted for C++14.
>=20
> Howard
>=20
>=20
> I disagree. That issue allows for trying moves first for more cases, but =
it still keeps the restriction (http://eel.is/c++draft/class.copy.elision#3=
..sentence-2), emphasis mine:
>=20
> > If the first overload resolution fails or was not performed, or if the =
type of the first parameter of the selected constructor is not an rvalue re=
ference to the object's type (possibly cv-qualified), overload resolution i=
s performed again, considering the object as an lvalue.
>=20
> CWG 1579 allowed this case to become a move:
>=20
> struct A {
>   A(std::string&&);
> };
>=20
> A f() {
>   std::string x;
>   return x; // move because of this issue
> }
>=20
> but not either of the examples I mentioned.
>=20
> --
> You received this message because you are subscribed to the Google Groups=
 "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an=
 email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit https://groups.google.com/a/isoc=
pp.org/d/msgid/std-proposals/25a4f822-e9f3-47ce-9458-d3dd6b242421%40isocpp.=
org.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/514667C3-9B3E-41DB-A31B-C6E401FC31A3%40gmail.com=
..

--Apple-Mail=_530CA5E9-1E56-481D-A8D1-4F0794EE8C36
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename=signature.asc
Content-Type: application/pgp-signature;
 name=signature.asc
Content-Description: Message signed with OpenPGP

-----BEGIN PGP SIGNATURE-----

iQIzBAEBCAAdFiEEfIiFcJYbP97+HbHHZtwcLEqqFYIFAltzkWUACgkQZtwcLEqq
FYIrYA//VeuXVu1wewdrKoWf/GXQEcEgOAfYZTQ+CnlS2B65KQ96w1Pt9CyszZNt
O+nqU1c6+sG7e05cD0TWSnZSlFPZmFFbzRtj3WI3q8b8X+jpPi+l5+Sv6O1ackKq
THHAogamOJ8Vumt5TDw7wHUCeQsdJBQLIRGE/vdJS28FtVxL1AvrFdx0VRQak+Ug
cUDOlmMNV5DlQy8tGuLg/i27QyPaeZHIoSQfGAhraoHTUpZfAry1cHKXq+G3+RfH
CoUm37NBiizbXxrrTK/6HnxKfgfyjX+AU2buaVB8xBWdcTamQhxyd7n9oZF4Ka3Q
5qHi07nnhIbUb0Rw5db29f83SLz8BN29cvrFWsyFZprhXbg1iCJoyu1x4xoykAie
xt4BU9ENkNfJYFyIs1YTS8F0lc2lwiEI/ZLn6i6I9bSnAk87kdhWK4bV+vN44csf
QsZ8+jsMi+WcD8BC9mZHxi3pGT4Yenvu91JU69P3131sQnwMTuzlrF9VXJJfEaI9
C6Y8fhiEeA72Cw5hP+JFDK+xJ2RthvAxdcCw2BmVTBCvy6iQL8qzBjKc0kPtFn8s
IVV6FlYSPn0yIl4Gu6q+GTof6X96OiPGxp1y33KfP/aSqMsxCff24CBmwiRSOS0b
aOWt4KRCw7Z6pzARUN1hChYYQy7+SjMUEjCLeE1aYDL0tBkkxN8=
=Us3a
-----END PGP SIGNATURE-----

--Apple-Mail=_530CA5E9-1E56-481D-A8D1-4F0794EE8C36--

.


Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date: Wed, 15 Aug 2018 16:47:02 -0700 (PDT)
Raw View
------=_Part_157_732471800.1534376822752
Content-Type: multipart/alternative;
 boundary="----=_Part_158_1163886275.1534376822752"

------=_Part_158_1163886275.1534376822752
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Tuesday, August 14, 2018 at 7:35:24 PM UTC-7, Howard Hinnant wrote:
>
> Thank you for the education!  I had no idea the rules were this screwed=
=20
> up.=20
>

Right up there with ADL. ;)

I'm attaching a new draft revision of D1155 "More implicit moves."  This=20
revision prominently incorporates Barry's "by-value sink" examples =E2=80=
=94 and I=20
decided to give the four classes of examples in the same order as their=20
controlling phrases appears in N4762, which means Barry gets his wish and=
=20
"slicing" moves to the very bottom of the list. :)

Based on feedback from David Stone, I've also shown the alternative wording=
=20
that would be proposed on the (IMHO good) assumption that P0527 is shortly=
=20
to be adopted by CWG.

Thanks to Howard for (even accidentally :)) reminding me to check GCC's=20
behavior. It turns out that GCC 5.1+ actually do the move in Barry's=20
examples, even though Clang doesn't do the move... and honestly I'm not=20
100% sure whether the Standard requires us to or not!  (The crux is what=20
does the Standard mean by the phrase "the selected constructor." P1155=20
deletes that troublesome phrase, meaning that the move will *definitely* be=
=20
required if we adopt P1155. Which is exactly what we want, IMHO.)

=E2=80=93Arthur

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/2a7d9fae-dd11-43e1-b15f-8c9043ece3df%40isocpp.or=
g.

------=_Part_158_1163886275.1534376822752
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Tuesday, August 14, 2018 at 7:35:24 PM UTC-7, Howard Hi=
nnant wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Thank you for the =
education! =C2=A0I had no idea the rules were this screwed up.
<br></blockquote><div><br></div><div>Right up there with ADL. ;)</div><div>=
<br></div><div>I&#39;m attaching a new draft revision of D1155 &quot;More i=
mplicit moves.&quot; =C2=A0This revision prominently incorporates Barry&#39=
;s &quot;by-value sink&quot; examples =E2=80=94 and I decided to give the f=
our classes of examples in the same order as their controlling phrases appe=
ars in N4762, which means Barry gets his wish and &quot;slicing&quot; moves=
 to the very bottom of the list. :)</div><div><br></div><div>Based on feedb=
ack from David Stone, I&#39;ve also shown the alternative wording that woul=
d be proposed on the (IMHO good) assumption that P0527 is shortly to be ado=
pted by CWG.</div><div><br></div><div>Thanks to Howard for (even accidental=
ly :)) reminding me to check GCC&#39;s behavior. It turns out that GCC 5.1+=
 actually do the move in Barry&#39;s examples, even though Clang doesn&#39;=
t do the move... and honestly I&#39;m not 100% sure whether the Standard re=
quires us to or not! =C2=A0(The crux is what does the Standard mean by the =
phrase &quot;the selected constructor.&quot; P1155 deletes that troublesome=
 phrase, meaning that the move will <i>definitely</i> be required if we ado=
pt P1155. Which is exactly what we want, IMHO.)<br></div><div><br></div><di=
v>=E2=80=93Arthur</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/2a7d9fae-dd11-43e1-b15f-8c9043ece3df%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/2a7d9fae-dd11-43e1-b15f-8c9043ece3df=
%40isocpp.org</a>.<br />

------=_Part_158_1163886275.1534376822752--

------=_Part_157_732471800.1534376822752
Content-Type: text/html; charset=UTF-8;
 name=more-implicit-moves-draft-6.html
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment; filename=more-implicit-moves-draft-6.html
X-Attachment-Id: 31611d80-8588-4c9c-a43a-1f81ae0c1818
Content-ID: <31611d80-8588-4c9c-a43a-1f81ae0c1818>

<!doctype html><html lang=3D"en">
 <head>
  <meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type">
  <meta content=3D"width=3Ddevice-width, initial-scale=3D1, shrink-to-fit=
=3Dno" name=3D"viewport">
  <title>D1155R0: More implicit moves</title>
<style data-fill-with=3D"stylesheet">/*************************************=
*****************************************
 *                   Style sheet for the W3C specifications                =
   *
 *
 * Special classes handled by this style sheet include:
 *
 * Indices
 *   - .toc for the Table of Contents (<ol class=3D"toc">)
 *     + <span class=3D"secno"> for the section numbers
 *   - #toc for the Table of Contents (<nav id=3D"toc">)
 *   - ul.index for Indices (<a href=3D"#ref">term</a><span>, in =C2=A7N.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=3D'complex data'> for extra-complex tables
 *     -> use <td class=3D'long'> for paragraph-length cell content
 *     -> use <td class=3D'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=3D'secn=
o'>3.2</span>)
 *   - .marker for source-inserted example/figure/issue numbers (<span clas=
s=3D'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 possi=
ble.
 *   - js-added ToC jump links (see fixup.js)
 *
 **************************************************************************=
****/

/**************************************************************************=
****/
/*                                   Body                                  =
   */
/**************************************************************************=
****/

=09body {
=09=09counter-reset: example figure issue;

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

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

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


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

/** Header ****************************************************************=
****/

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

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

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

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

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

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

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

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

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

/** Copyright *************************************************************=
****/

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

/**************************************************************************=
****/
/*                                Sectioning                               =
   */
/**************************************************************************=
****/

/** Headings **************************************************************=
****/

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

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

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

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

/** Subheadings ***********************************************************=
****/

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

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

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

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

=09p {
=09=09margin: 1em 0;
=09}

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

/**************************************************************************=
****/
/*                                    Code                                 =
   */
/**************************************************************************=
****/

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

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

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

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

  /* Do something nice. */

/**************************************************************************=
****/
/*                                    Links                                =
   */
/**************************************************************************=
****/

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

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

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

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

/**************************************************************************=
****/
/*                                    Images                               =
   */
/**************************************************************************=
****/

=09img {
=09=09border-style: none;
=09}

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

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

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

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

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

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

/** Blockquotes ***********************************************************=
****/

=09blockquote {
=09=09border-color: silver;
=09}

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

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

/** Example ***************************************************************=
****/

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

/**************************************************************************=
****/
/*                                    Tables                               =
   */
/**************************************************************************=
****/

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


/*
Alternate table alignment rules

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

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

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

Possible extra rowspan handling

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

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

/**************************************************************************=
****/
/*                                  Indices                                =
   */
/**************************************************************************=
****/


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

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

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

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

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

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

=09=09.toc li {
=09=09=09clear: both;
=09=09}

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

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

=09@supports (display:grid) {
=09=09/* Use #toc over .toc to override non-@supports rules. */
=09=09#toc {
=09=09=09display: grid;
=09=09=09align-content: start;
=09=09=09grid-template-columns: auto 1fr;
=09=09=09grid-column-gap: 1rem;
=09=09=09column-gap: 1rem;
=09=09=09grid-row-gap: .6rem;
=09=09=09row-gap: .6rem;
=09=09}
=09=09#toc h2 {
=09=09=09grid-column: 1 / -1;
=09=09=09margin-bottom: 0;
=09=09}
=09=09#toc ol,
=09=09#toc li,
=09=09#toc a {
=09=09=09display: contents;
=09=09=09/* Switch <a> to subgrid when supported */
=09=09}
=09=09#toc span {
=09=09=09margin: 0;
=09=09}
=09=09#toc > .toc > li > a > span {
=09=09=09/* The spans of the top-level list,
=09=09=09   comprising the first items of each top-level section. */
=09=09=09margin-top: 1.1rem;
=09=09}
=09=09#toc#toc .secno { /* Ugh, need more specificity to override base.css =
*/
=09=09=09grid-column: 1;
=09=09=09width: auto;
=09=09=09margin-left: 0;
=09=09}
=09=09#toc .content {
=09=09=09grid-column: 2;
=09=09=09width: auto;
=09=09=09margin-right: 1rem;
=09=09}
=09=09#toc .content:hover {
=09=09=09background: rgba(75%, 75%, 75%, .25);
=09=09=09border-bottom: 3px solid #054572;
=09=09=09margin-bottom: -3px;
=09=09}
=09=09#toc li li li .content {
=09=09=09margin-left: 1rem;
=09=09}
=09=09#toc li li li li .content {
=09=09=09margin-left: 2rem;
=09=09}
=09}


/** Index *****************************************************************=
****/

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

/** Index Tables *****************************************************/
=09/* See also the data table styling section, which this effectively subcl=
asses */

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

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

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

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

/**************************************************************************=
****/
/*                                    Print                                =
   */
/**************************************************************************=
****/

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

/**************************************************************************=
****/
/*                                    Legacy                               =
   */
/**************************************************************************=
****/

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



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

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

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

=09@media not print {
=09=09.overlarge {
=09=09=09overflow-x: auto;
=09=09=09/* See Lea Verou's explanation background-attachment:
=09=09=09 * http://lea.verou.me/2012/04/background-attachment-local/
=09=09=09 *
=09=09=09background: top left  / 4em 100% linear-gradient(to right,  #fffff=
f, rgba(255, 255, 255, 0)) local,
=09=09=09            top right / 4em 100% linear-gradient(to left, #ffffff,=
 rgba(255, 255, 255, 0)) local,
=09=09=09            top left  / 1em 100% linear-gradient(to right,  #c3c3c=
5, rgba(195, 195, 197, 0)) scroll,
=09=09=09            top right / 1em 100% linear-gradient(to left, #c3c3c5,=
 rgba(195, 195, 197, 0)) scroll,
=09=09=09            white;
=09=09=09background-repeat: no-repeat;
=09=09=09*/
=09=09}
=09}
</style>
<style type=3D"text/css">
    table, th, td {
      border: 1px solid black;
      border-collapse: collapse;
      vertical-align: top;
    }
    th, td {
      border-left: none;
      border-right: none;
      padding: 0px 10px;
    }
    th {
      text-align: center;
    }
  </style>
  <meta content=3D"Bikeshed version aab07fa3563472bb567b6a05ef64a9084da5332=
7" name=3D"generator">
  <link href=3D"https://isocpp.org/favicon.ico" rel=3D"icon">
<style>
hilite  {background-color: #FFFF00; font-weight: bold;}
ins  {background-color: #CCFFCC; text-decoration: underline;}
del  {background-color: #FFCACA; text-decoration: line-through;}
</style>
<style>/* style-md-lists */

/* This is a weird hack for me not yet following the commonmark spec
   regarding paragraph and lists. */
[data-md] > :first-child {
    margin-top: 0;
}
[data-md] > :last-child {
    margin-bottom: 0;
}</style>
<style>/* style-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: "=C2=B6"; }
..heading > a.self-link::before { content: "=C2=A7"; }
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: "=E2=80=98";
}
..css::after, .property::after, .descriptor::after {
    content: "=E2=80=99";
}
..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=3D"property"]::before,
[data-link-type=3D"propdesc"]::before,
[data-link-type=3D"descriptor"]::before,
[data-link-type=3D"value"]::before,
[data-link-type=3D"function"]::before,
[data-link-type=3D"at-rule"]::before,
[data-link-type=3D"selector"]::before,
[data-link-type=3D"maybe"]::before {
    content: "=E2=80=98";
}
[data-link-type=3D"property"]::after,
[data-link-type=3D"propdesc"]::after,
[data-link-type=3D"descriptor"]::after,
[data-link-type=3D"value"]::after,
[data-link-type=3D"function"]::after,
[data-link-type=3D"at-rule"]::after,
[data-link-type=3D"selector"]::after,
[data-link-type=3D"maybe"]::after {
    content: "=E2=80=99";
}

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

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

[data-link-type=3Dbiblio] {
    white-space: pre;
}</style>
 <body class=3D"h-entry">
  <div class=3D"head">
   <p data-fill-with=3D"logo"></p>
   <h1 class=3D"p-name no-ref" id=3D"title">D1155R0<br>More implicit moves<=
/h1>
   <h2 class=3D"no-num no-toc no-ref heading settled" id=3D"subtitle"><span=
 class=3D"content">Draft Proposal, <time class=3D"dt-updated" datetime=3D"2=
018-08-15">2018-08-15</time></span></h2>
   <div data-fill-with=3D"spec-metadata">
    <dl>
     <dt>Author:
     <dd>
      <dd class=3D"editor p-author h-card vcard"><a class=3D"p-name fn u-em=
ail email" href=3D"mailto:arthur.j.odwyer@gmail.com">Arthur O'Dwyer</a>
     <dt>Audience:
     <dd>EWG
     <dt>Project:
     <dd>ISO/IEC JTC1/SC22/WG21 14882: Programming Language =E2=80=94 C++
     <dt>Draft Revision:
     <dd>6
     <dt>Current Source:
     <dd><a href=3D"https://github.com/Quuxplusone/draft/blob/gh-pages/d115=
5-more-implicit-moves.bs">github.com/Quuxplusone/draft/blob/gh-pages/d1155-=
more-implicit-moves.bs</a>
     <dt>Current:
     <dd><a href=3D"https://rawgit.com/Quuxplusone/draft/gh-pages/d1155-mor=
e-implicit-moves.html">rawgit.com/Quuxplusone/draft/gh-pages/d1155-more-imp=
licit-moves.html</a>
    </dl>
   </div>
   <div data-fill-with=3D"warning"></div>
   <hr title=3D"Separator for header">
  </div>
  <div class=3D"p-summary" data-fill-with=3D"abstract">
   <h2 class=3D"no-num no-toc no-ref heading settled" id=3D"abstract"><span=
 class=3D"content">Abstract</span></h2>
   <p>Programmers expect <code class=3D"highlight"><c- k>return</c-> <c- n>=
x</c-><c- p>;</c-></code> to trigger copy elision; or, at worst, to <i>impl=
icitly move</i> from <code class=3D"highlight"><c- n>x</c-></code> instead =
of copying. Occasionally, C++ violates their expectations and performs
an expensive copy anyway.
Based on our experience using Clang to diagnose unexpected copies in Chromi=
um, Mozilla,
and LibreOffice, we propose to change the standard so that these copies wil=
l be replaced with <i>implicit moves</i>.</p>
  </div>
  <nav data-fill-with=3D"table-of-contents" id=3D"toc">
   <h2 class=3D"no-num no-toc no-ref" id=3D"contents">Table of Contents</h2=
>
   <ol class=3D"toc" role=3D"directory">
    <li>
     <a href=3D"#background"><span class=3D"secno">1</span> <span class=3D"=
content">Background</span></a>
     <ol class=3D"toc">
      <li><a href=3D"#throwing"><span class=3D"secno">1.1</span> <span clas=
s=3D"content">Throwing is pessimized</span></a>
      <li><a href=3D"#conversion"><span class=3D"secno">1.2</span> <span cl=
ass=3D"content">Non-constructor conversion is pessimized</span></a>
      <li><a href=3D"#sinks"><span class=3D"secno">1.3</span> <span class=
=3D"content">By-value sinks are pessimized</span></a>
      <li><a href=3D"#slicing"><span class=3D"secno">1.4</span> <span class=
=3D"content">Slicing is pessimized</span></a>
     </ol>
    <li><a href=3D"#wording"><span class=3D"secno">2</span> <span class=3D"=
content">Proposed wording relative to N4762</span></a>
    <li><a href=3D"#wording-alt"><span class=3D"secno">3</span> <span class=
=3D"content">Proposed wording relative to P0527r1</span></a>
    <li>
     <a href=3D"#implementation"><span class=3D"secno">4</span> <span class=
=3D"content">Implementation experience</span></a>
     <ol class=3D"toc">
      <li><a href=3D"#true-positives"><span class=3D"secno">4.1</span> <spa=
n class=3D"content">Plenitude of true positives</span></a>
      <li><a href=3D"#false-positives"><span class=3D"secno">4.2</span> <sp=
an class=3D"content">Lack of false positives</span></a>
     </ol>
    <li><a href=3D"#acknowledgments"><span class=3D"secno">5</span> <span c=
lass=3D"content">Acknowledgments</span></a>
    <li>
     <a href=3D"#references"><span class=3D"secno"></span> <span class=3D"c=
ontent">References</span></a>
     <ol class=3D"toc">
      <li><a href=3D"#informative"><span class=3D"secno"></span> <span clas=
s=3D"content">Informative References</span></a>
     </ol>
   </ol>
  </nav>
  <main>
   <h2 class=3D"heading settled" data-level=3D"1" id=3D"background"><span c=
lass=3D"secno">1. </span><span class=3D"content">Background</span><a class=
=3D"self-link" href=3D"#background"></a></h2>
   <p>Each version of C++ has improved the efficiency of returning objects =
by value. By the middle of the last
decade, copy elision was reliable (if not technically guaranteed) in situat=
ions like this:</p>
<pre class=3D"language-c++ highlight"><c- n>Widget</c-> <c- nf>one</c-><c- =
p>()</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>Widget</c-><c- p>();</c->  <c- c1>// copy elisi=
on</c->
<c- p>}</c->
<c- n>Widget</c-> <c- nf>two</c-><c- p>()</c-> <c- p>{</c->
    <c- n>Widget</c-> <c- n>result</c-><c- p>;</c->
    <c- k>return</c-> <c- n>result</c-><c- p>;</c->  <c- c1>// copy elision=
</c->
<c- p>}</c->
</pre>
   <p>In C++11, a completely new feature was added: a change to overload re=
solution which I will call <em>implicit move</em>. Even when copy elision i=
s impossible, the compiler is sometimes
required to <em>implicitly move</em> the <code class=3D"highlight"><c- k>re=
turn</c-></code> statement=E2=80=99s operand into the result object:</p>
<pre class=3D"language-c++ highlight"><c- n>std</c-><c- o>::</c-><c- n>shar=
ed_ptr</c-><c- o>&lt;</c-><c- n>Base</c-><c- o>></c-> <c- n>three</c-><c- p=
>()</c-> <c- p>{</c->
    <c- n>std</c-><c- o>::</c-><c- n>shared_ptr</c-><c- o>&lt;</c-><c- n>Ba=
se</c-><c- o>></c-> <c- n>result</c-><c- p>;</c->
    <c- k>return</c-> <c- n>result</c-><c- p>;</c->  <c- c1>// copy elision=
</c->
<c- p>}</c->
<c- n>std</c-><c- o>::</c-><c- n>shared_ptr</c-><c- o>&lt;</c-><c- n>Base</=
c-><c- o>></c-> <c- n>four</c-><c- p>()</c-> <c- p>{</c->
    <c- n>std</c-><c- o>::</c-><c- n>shared_ptr</c-><c- o>&lt;</c-><c- n>De=
rived</c-><c- o>></c-> <c- n>result</c-><c- p>;</c->
    <c- k>return</c-> <c- n>result</c-><c- p>;</c->  <c- c1>// no copy elis=
ion, but implicitly moved (not copied)</c->
<c- p>}</c->
</pre>
   <p>The wording for this optimization was amended by <a data-link-type=3D=
"biblio" href=3D"#biblio-cwg1579">[CWG1579]</a>. The current wording in <a =
href=3D"http://eel.is/c++draft/class.copy.elision#3">[class.copy.elision]/3=
</a> says:</p>
   <blockquote>
    <p>In the following copy-initialization contexts, a move operation migh=
t be used instead of a copy operation:</p>
    <ul>
     <li data-md>
      <p>If the <em>expression</em> in a <code class=3D"highlight"><c- k>re=
turn</c-></code> statement is a (possibly parenthesized) <em>id-expression<=
/em> that
names an object with automatic storage duration declared in the body or <em=
>parameter-declaration-clause</em> of the innermost enclosing function or <=
em>lambda-expression</em>, or</p>
     <li data-md>
      <p>
       if the operand of a <em>throw-expression</em> is the name of a non-v=
olatile automatic object
(other than a=20
       <hilite>function</hilite>
        or catch-clause parameter) whose scope does not extend beyond
the end of the innermost enclosing <em>try-block</em> (if there is one),
      </p>
    </ul>
    <p>
     overload resolution to select the constructor for the copy is first pe=
rformed as if the object were
designated by an rvalue. If the first overload resolution fails or was not =
performed, or if the type
of the first parameter of the selected=20
     <hilite>constructor</hilite>
      is not an=20
     <hilite>rvalue
reference</hilite>
      to=20
     <hilite>the object=E2=80=99s</hilite>
      type
(possibly cv-qualified), overload resolution is performed again, considerin=
g the object as an lvalue.
    </p>
   </blockquote>
   <p>The highlighted phrases above indicate places where the wording diver=
ges from a na=C3=AFve programmer=E2=80=99s intuition.
Consider the following <a href=3D"https://godbolt.org/g/9n8cwh">examples</a=
>...</p>
   <h3 class=3D"heading settled" data-level=3D"1.1" id=3D"throwing"><span c=
lass=3D"secno">1.1. </span><span class=3D"content">Throwing is pessimized</=
span><a class=3D"self-link" href=3D"#throwing"></a></h3>
   <p>
    Throwing is pessimized because of the highlighted word=20
    <hilite>function</hilite>
     [parameter].
   </p>
<pre class=3D"language-c++ highlight"><c- b>void</c-> <c- nf>five</c-><c- p=
>()</c-> <c- p>{</c->
    <c- n>Widget</c-> <c- n>w</c-><c- p>;</c->
    <c- n>throw</c-> <c- n>w</c-><c- p>;</c->  <c- c1>// non-guaranteed cop=
y elision, but implicitly moved (never copied)</c->
<c- p>}</c->
<c- n>Widget</c-> <c- nf>six</c-><c- p>(</c-><c- n>Widget</c-> <c- n>w</c->=
<c- p>)</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>w</c-><c- p>;</c->  <c- c1>// no copy elision, =
but implicitly moved (never copied)</c->
<c- p>}</c->
<c- b>void</c-> <c- nf>seven</c-><c- p>(</c-><c- n>Widget</c-> <c- n>w</c->=
<c- p>)</c-> <c- p>{</c->
    <c- n>throw</c-> <c- n>w</c-><c- p>;</c->  <c- c1>// no copy elision, a=
nd no implicit move (the object is copied)</c->
<c- p>}</c->
</pre>
   <p class=3D"note" role=3D"note"><span>Note:</span> The comment in <code =
class=3D"highlight"><c- n>seven</c-></code> matches the current Standard wo=
rding, and matches GCC=E2=80=99s behavior.
Clang=E2=80=99s behavior <em>already</em>, since Clang 4.0.1 or earlier, is=
 to do the implicit move.</p>
   <h3 class=3D"heading settled" data-level=3D"1.2" id=3D"conversion"><span=
 class=3D"secno">1.2. </span><span class=3D"content">Non-constructor conver=
sion is pessimized</span><a class=3D"self-link" href=3D"#conversion"></a></=
h3>
   <p>
    Non-constructor conversion is pessimized because of the highlighted wor=
d=20
    <hilite>constructor</hilite>
    .
   </p>
<pre class=3D"language-c++ highlight"><c- k>struct</c-> <c- n>From</c-> <c-=
 p>{</c->
    <c- n>From</c-><c- p>(</c-><c- n>Widget</c-> <c- k>const</c-> <c- o>&am=
p;</c-><c- p>);</c->
    <c- n>From</c-><c- p>(</c-><c- n>Widget</c-><c- o>&amp;&amp;</c-><c- p>=
);</c->
<c- p>};</c->

<c- k>struct</c-> <c- n>To</c-> <c- p>{</c->
    <c- n>operator</c-> <c- n>Widget</c-><c- p>()</c-> <c- k>const</c-> <c-=
 o>&amp;</c-><c- p>;</c->
    <c- n>operator</c-> <c- nf>Widget</c-><c- p>()</c-> <c- o>&amp;&amp;</c=
-><c- p>;</c->
<c- p>};</c->

<c- n>From</c-> <c- nf>eight</c-><c- p>()</c-> <c- p>{</c->
    <c- n>Widget</c-> <c- n>w</c-><c- p>;</c->
    <c- k>return</c-> <c- n>w</c-><c- p>;</c->  <c- c1>// no copy elision, =
but implicitly moved (never copied)</c->
<c- p>}</c->
<c- n>Widget</c-> <c- nf>nine</c-><c- p>()</c-> <c- p>{</c->
    <c- n>To</c-> <c- n>t</c-><c- p>;</c->
    <c- k>return</c-> <c- n>t</c-><c- p>;</c->  <c- c1>// no copy elision, =
and no implicit move (the object is copied)</c->
<c- p>}</c->
</pre>
   <h3 class=3D"heading settled" data-level=3D"1.3" id=3D"sinks"><span clas=
s=3D"secno">1.3. </span><span class=3D"content">By-value sinks are pessimiz=
ed</span><a class=3D"self-link" href=3D"#sinks"></a></h3>
   <p>
    By-value sinks are pessimized because of the highlighted phrase=20
    <hilite>rvalue reference</hilite>
    .
   </p>
<pre class=3D"language-c++ highlight"><c- k>struct</c-> <c- n>Fish</c-> <c-=
 p>{</c->
    <c- n>Fish</c-><c- p>(</c-><c- n>Widget</c-> <c- k>const</c-> <c- o>&am=
p;</c-><c- p>);</c->
    <c- n>Fish</c-><c- p>(</c-><c- n>Widget</c-><c- o>&amp;&amp;</c-><c- p>=
);</c->
<c- p>};</c->

<c- k>struct</c-> <c- n>Fowl</c-> <c- p>{</c->
    <c- n>Fowl</c-><c- p>(</c-><c- n>Widget</c-><c- p>);</c->
<c- p>};</c->

<c- n>Fish</c-> <c- nf>ten</c-><c- p>()</c-> <c- p>{</c->
    <c- n>Widget</c-> <c- n>w</c-><c- p>;</c->
    <c- k>return</c-> <c- n>w</c-><c- p>;</c->  <c- c1>// no copy elision, =
but implicitly moved (never copied)</c->
<c- p>}</c->
<c- n>Fowl</c-> <c- nf>eleven</c-><c- p>()</c-> <c- p>{</c->
    <c- n>Widget</c-> <c- n>w</c-><c- p>;</c->
    <c- k>return</c-> <c- n>w</c-><c- p>;</c->  <c- c1>// no copy elision, =
and no implicit move (the Widget object is copied)</c->
<c- p>}</c->
</pre>
   <p class=3D"note" role=3D"note"><span>Note:</span> The comment in <code =
class=3D"highlight"><c- n>eleven</c-></code> matches the current Standard w=
ording, and matches Clang=E2=80=99s behavior.
GCC=E2=80=99s behavior <em>already</em>, since GCC 5.1, is to do the implic=
it move.</p>
   <h3 class=3D"heading settled" data-level=3D"1.4" id=3D"slicing"><span cl=
ass=3D"secno">1.4. </span><span class=3D"content">Slicing is pessimized</sp=
an><a class=3D"self-link" href=3D"#slicing"></a></h3>
   <p>
    Slicing is pessimized because of the highlighted phrase=20
    <hilite>the object=E2=80=99s</hilite>
    .
   </p>
<pre class=3D"language-c++ highlight"><c- n>std</c-><c- o>::</c-><c- n>shar=
ed_ptr</c-><c- o>&lt;</c-><c- n>Base</c-><c- o>></c-> <c- n>twelve</c-><c- =
p>()</c-> <c- p>{</c->
    <c- n>std</c-><c- o>::</c-><c- n>shared_ptr</c-><c- o>&lt;</c-><c- n>De=
rived</c-><c- o>></c-> <c- n>result</c-><c- p>;</c->
    <c- k>return</c-> <c- n>result</c-><c- p>;</c->  <c- c1>// no copy elis=
ion, but implicitly moved (never copied)</c->
<c- p>}</c->
<c- n>Base</c-> <c- n>thirteen</c-><c- p>()</c-> <c- p>{</c->
    <c- n>Derived</c-> <c- n>result</c-><c- p>;</c->
    <c- k>return</c-> <c- n>result</c-><c- p>;</c->  <c- c1>// no copy elis=
ion, and no implicit move (the object is copied)</c->
<c- p>}</c->
</pre>
   <p class=3D"note" role=3D"note"><span>Note:</span> The comment in <code =
class=3D"highlight"><c- n>thirteen</c-></code> matches the current Standard=
 wording, and matches Clang=E2=80=99s behavior.
GCC=E2=80=99s behavior <em>already</em>, since GCC 8.1, is to do the implic=
it move.</p>
   <p>We propose to remove all four of these unnecessary limitations.</p>
   <h2 class=3D"heading settled" data-level=3D"2" id=3D"wording"><span clas=
s=3D"secno">2. </span><span class=3D"content">Proposed wording relative to =
N4762</span><a class=3D"self-link" href=3D"#wording"></a></h2>
   <p>Modify <a href=3D"http://eel.is/c++draft/class.copy.elision#3">[class=
..copy.elision]/3</a> as follows:</p>
   <blockquote>
    <p>In the following copy-initialization contexts, a move operation migh=
t be used instead of a copy operation:</p>
    <ul>
     <li data-md>
      <p>If the <em>expression</em> in a <code class=3D"highlight"><c- k>re=
turn</c-></code> statement is a (possibly parenthesized) <em>id-expression<=
/em> that
names an object with automatic storage duration declared in the body or <em=
>parameter-declaration-clause</em> of the innermost enclosing function or <=
em>lambda-expression</em>, or</p>
     <li data-md>
      <p>
       if the operand of a <em>throw-expression</em> is the name of a non-v=
olatile automatic object
(other than a=20
       <del>function or</del>
        catch-clause parameter) whose scope does not extend beyond
the end of the innermost enclosing <em>try-block</em> (if there is one),
      </p>
    </ul>
    <p>
     overload resolution to select the constructor for the copy is first pe=
rformed as if the object were
designated by an rvalue. If the first overload resolution fails or was not =
performed,=20
     <del>or if the type
of the first parameter of the selected constructor is not an rvalue referen=
ce to the object=E2=80=99s type
(possibly cv-qualified),</del>
      overload resolution is performed again, considering the object as an =
lvalue.
[<em>Note:</em> This two-stage overload resolution must be performed regard=
less of whether copy elision will occur.
It determines the constructor to be called if elision is not performed, and=
 the selected constructor
must be accessible even if the call is elided. =E2=80=94<em>end note</em>]
    </p>
   </blockquote>
   <p class=3D"note" role=3D"note"><span>Note:</span> I believe that the tw=
o instances of the word "constructor" in the quoted note remain correct. Th=
ey
refer to the constructor selected to initialize the result object, as the v=
ery last step of the conversion
sequence. This proposed change merely permits the conversion sequence to be=
 longer than a single step; for
example, it might involve a derived-to-base conversion followed by a move-c=
onstructor, or a user-defined
conversion operator followed by a move-constructor. In either case, as far =
as the quoted note is concerned,
that ultimate move-constructor is the "constructor to be called," and indee=
d it must be accessible
even if elision is performed.</p>
   <h2 class=3D"heading settled" data-level=3D"3" id=3D"wording-alt"><span =
class=3D"secno">3. </span><span class=3D"content">Proposed wording relative=
 to P0527r1</span><a class=3D"self-link" href=3D"#wording-alt"></a></h2>
   <p>David Stone=E2=80=99s <a data-link-type=3D"biblio" href=3D"#biblio-p0=
527">[P0527]</a> "Implicitly move from rvalue references in return statemen=
ts" proposes to
alter the current rules "references are never implicitly moved-from" and "c=
atch-clause parameters
are never implicitly moved-from." It accomplishes this by significantly ref=
actoring clause <a href=3D"http://eel.is/c++draft/class.copy.elision#3">[cl=
ass.copy.elision]/3</a>.</p>
   <p>In the case that <a data-link-type=3D"biblio" href=3D"#biblio-p0527">=
[P0527]</a>'s changes are adopted into C++2a, we propose to modify the new =
<a href=3D"http://eel.is/c++draft/class.copy.elision#3">[class.copy.elision=
]/3</a> as follows:</p>
   <blockquote>
    <p>
     A <em>movable entity</em> is a non-volatile object or an rvalue refere=
nce to a non-volatile type,
in either case with automatic storage duration.=20
     <del>The underlying type of a movable entity is
the type of the object or the referenced type, respectively.</del>
      In the following
copy-initialization contexts, a move operation might be used instead of a c=
opy operation:
    </p>
    <ul>
     <li data-md>
      <p>If the <em>expression</em> in a <code class=3D"highlight"><c- k>re=
turn</c-></code> statement is a (possibly parenthesized) <em>id-expression<=
/em> that
names a movable entity declared in the body or <em>parameter-declaration-cl=
ause</em> of the innermost enclosing function or <em>lambda-expression</em>=
, or</p>
     <li data-md>
      <p>if the operand of a <em>throw-expression</em> is a (possibly paren=
thesized) <em>id-expression</em> that
names a movable entity whose scope does not extend beyond
the end of the innermost enclosing <em>try-block</em> (if there is one),</p=
>
    </ul>
    <p>
     overload resolution to select the constructor for the copy is first pe=
rformed as if the entity were
designated by an rvalue. If the first overload resolution fails or was not =
performed,=20
     <del>or if the type
of the first parameter of the selected constructor is not an rvalue referen=
ce to the (possibly cv-qualified)
underlying type of the movable entity,</del>
      overload resolution is performed again, considering the entity as an =
lvalue.
[<em>Note:</em> This two-stage overload resolution must be performed regard=
less of whether copy elision will occur.
It determines the constructor to be called if elision is not performed, and=
 the selected constructor
must be accessible even if the call is elided. =E2=80=94<em>end note</em>]
    </p>
   </blockquote>
   <h2 class=3D"heading settled" data-level=3D"4" id=3D"implementation"><sp=
an class=3D"secno">4. </span><span class=3D"content">Implementation experie=
nce</span><a class=3D"self-link" href=3D"#implementation"></a></h2>
   <p>This feature has effectively already been implemented in Clang since =
February 2018; see <a data-link-type=3D"biblio" href=3D"#biblio-d43322">[D4=
3322]</a>.
Under the diagnostic option <code class=3D"highlight"><c- o>-</c-><c- n>Wre=
turn</c-><c- o>-</c-><c- n>std</c-><c- o>-</c-><c- n>move</c-></code> (whic=
h is enabled as part of <code class=3D"highlight"><c- o>-</c-><c- n>Wmove</=
c-></code>, <code class=3D"highlight"><c- o>-</c-><c- n>Wmost</c-></code>, =
and <code class=3D"highlight"><c- o>-</c-><c- n>Wall</c-></code>),
the compiler performs overload resolution according to <em>both</em> rules =
=E2=80=94 the standard rule and also
the rule proposed in this proposal. If the two resolutions produce differen=
t results, then Clang
emits a warning diagnostic explaining that the return value will not be imp=
licitly moved and
suggesting that the programmer add an explicit <code class=3D"highlight"><c=
- n>std</c-><c- o>::</c-><c- n>move</c-></code>.</p>
   <p>However, the Clang diagnostic does not diagnose the "By-value sinks" =
examples above (<code class=3D"highlight"><c- n>ten</c-></code> and <code c=
lass=3D"highlight"><c- n>eleven</c-></code>).</p>
   <h3 class=3D"heading settled" data-level=3D"4.1" id=3D"true-positives"><=
span class=3D"secno">4.1. </span><span class=3D"content">Plenitude of true =
positives</span><a class=3D"self-link" href=3D"#true-positives"></a></h3>
   <p>These warning diagnostics have proven helpful on real code.
Many instances have been reported of code that is currently accidentally pe=
ssimized,
and which would become optimized (with no loss of correctness) if this prop=
osal were adopted:</p>
   <ul>
    <li data-md>
     <p><a data-link-type=3D"biblio" href=3D"#biblio-sg14">[SG14]</a>: a cl=
ever trick to reduce code duplication by using conversion operators,
rather than converting constructors, turned out to cause unnecessary copyin=
g in a common use-case.</p>
    <li data-md>
     <p><a data-link-type=3D"biblio" href=3D"#biblio-chromium">[Chromium]</=
a>: a non-standard container library used <code class=3D"highlight"><c- n>i=
terator</c-><c- o>::</c-><c- k>operator</c-> <c- n>const_iterator</c-><c- p=
>()</c-> <c- o>&amp;&amp;</c-></code> instead of <code class=3D"highlight">=
<c- n>const_iterator</c-><c- o>::</c-><c- n>const_iterator</c-><c- p>(</c->=
<c- n>iterator</c-><c- o>&amp;&amp;</c-><c- p>)</c-></code>.
(The actual committed diff is <a href=3D"https://chromium-review.googlesour=
ce.com/c/chromium/src/+/1025435">here</a>.)</p>
    <li data-md>
     <p><a data-link-type=3D"biblio" href=3D"#biblio-libreoffice">[LibreOff=
ice]</a>: "An explicit std::move would be needed in the return statements, =
as there=E2=80=99s a
conversion from <code class=3D"highlight"><c- n>VclPtrInstance</c-></code> =
to base class <code class=3D"highlight"><c- n>VclPtr</c-></code> involved."=
</p>
   </ul>
   <p>However, we must note that about half of the true positives from the =
diagnostic are on code
like the following example, which is not affected by this proposal:</p>
<pre class=3D"language-c++ highlight"><c- n>std</c-><c- o>::</c-><c- n>stri=
ng</c-> <c- n>fourteen</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>str=
ing</c-><c- o>&amp;&amp;</c-> <c- n>s</c-><c- p>)</c-> <c- p>{</c->
    <c- n>s</c-> <c- o>+=3D</c-> <c- s>"foo"</c-><c- p>;</c->
    <c- k>return</c-> <c- n>s</c-><c- p>;</c->  <c- c1>// no copy elision, =
and no implicit move (the object is copied)</c->
<c- p>}</c->
</pre>
   <p>See <a data-link-type=3D"biblio" href=3D"#biblio-khronos">[Khronos]</=
a>, <a data-link-type=3D"biblio" href=3D"#biblio-folly">[Folly]</a>, and th=
ree of the four diffs in <a data-link-type=3D"biblio" href=3D"#biblio-chrom=
ium">[Chromium]</a>. <a data-link-type=3D"biblio" href=3D"#biblio-aws">[AWS=
]</a> is a particularly egregious variation. (The committed diff is <a href=
=3D"https://github.com/aws/aws-sdk-cpp/commit/ded84836cd7bf15aa2375a6c1f714=
3f34d985df1#diff-2ce19b694bb11d0ff1676f740d32f98dL136">here</a>.)</p>
<pre class=3D"language-c++ highlight"><c- n>std</c-><c- o>::</c-><c- n>stri=
ng</c-> <c- n>fifteen</c-><c- p>()</c-> <c- p>{</c->
    <c- n>std</c-><c- o>::</c-><c- n>string</c-><c- o>&amp;&amp;</c-> <c- n=
>s</c-> <c- o>=3D</c-> <c- s>"hello world"</c-><c- p>;</c->
    <c- k>return</c-> <c- n>s</c-><c- p>;</c->  <c- c1>// no copy elision, =
and no implicit move (the object is copied)</c->
<c- p>}</c->
</pre>
   <p>Some number of programmers certainly expect a move here, and in fact =
<a data-link-type=3D"biblio" href=3D"#biblio-p0527">[P0527]</a> proposes
to implicitly move in both of these cases. This paper does not conflict wit=
h <a data-link-type=3D"biblio" href=3D"#biblio-p0527">[P0527]</a>,
and we provide <a href=3D"#wording-alt">an alternative wording</a> for the =
case that <a data-link-type=3D"biblio" href=3D"#biblio-p0527">[P0527]</a> i=
s adopted.</p>
   <h3 class=3D"heading settled" data-level=3D"4.2" id=3D"false-positives">=
<span class=3D"secno">4.2. </span><span class=3D"content">Lack of false pos=
itives</span><a class=3D"self-link" href=3D"#false-positives"></a></h3>
   <p>In five months we have received a single "false positive" report (<a =
data-link-type=3D"biblio" href=3D"#biblio-mozilla">[Mozilla]</a>), which co=
mplained that the move-constructor suggested
by Clang was <em>not significantly more efficient</em> than the actually se=
lected copy-constructor. The programmer preferred not
to add the suggested <code class=3D"highlight"><c- n>std</c-><c- o>::</c-><=
c- n>move</c-></code> because the code ugliness was not worth the minor per=
formance gain.
This proposal would give Mozilla that minor performance gain without the ug=
liness =E2=80=94 the best of both worlds!</p>
   <p>We have never received any bug report that the move-constructor sugge=
sted by Clang would have been incorrect.</p>
   <h2 class=3D"heading settled" data-level=3D"5" id=3D"acknowledgments"><s=
pan class=3D"secno">5. </span><span class=3D"content">Acknowledgments</span=
><a class=3D"self-link" href=3D"#acknowledgments"></a></h2>
   <ul>
    <li data-md>
     <p>Thanks to Lukas Bergdoll for his copious feedback.</p>
    <li data-md>
     <p>Thanks to David Stone for <a data-link-type=3D"biblio" href=3D"#bib=
lio-p0527">[P0527]</a>.</p>
    <li data-md>
     <p>Thanks to Barry Revzin (see <a data-link-type=3D"biblio" href=3D"#b=
iblio-revzin">[Revzin]</a>) for pointing out the "By-value sinks" case.</p>
   </ul>
  </main>
<script>
(function() {
  "use strict";
  var collapseSidebarText =3D '<span aria-hidden=3D"true">=E2=86=90</span> =
'
                          + '<span>Collapse Sidebar</span>';
  var expandSidebarText   =3D '<span aria-hidden=3D"true">=E2=86=92</span> =
'
                          + '<span>Pop Out Sidebar</span>';
  var tocJumpText         =3D '<span aria-hidden=3D"true">=E2=86=91</span> =
'
                          + '<span>Jump to Table of Contents</span>';

  var sidebarMedia =3D window.matchMedia('screen and (min-width: 78em)');
  var autoToggle   =3D function(e){ toggleSidebar(e.matches) };
  if(sidebarMedia.addListener) {
    sidebarMedia.addListener(autoToggle);
  }

  function toggleSidebar(on) {
    if (on =3D=3D undefined) {
      on =3D !document.body.classList.contains('toc-sidebar');
    }

    /* Don=E2=80=99t scroll to compensate for the ToC if we=E2=80=99re abov=
e it already. */
    var headY =3D 0;
    var head =3D document.querySelector('.head');
    if (head) {
      // terrible approx of "top of ToC"
      headY +=3D head.offsetTop + head.offsetHeight;
    }
    var skipScroll =3D window.scrollY < headY;

    var toggle =3D document.getElementById('toc-toggle');
    var tocNav =3D document.getElementById('toc');
    if (on) {
      var tocHeight =3D tocNav.offsetHeight;
      document.body.classList.add('toc-sidebar');
      document.body.classList.remove('toc-inline');
      toggle.innerHTML =3D collapseSidebarText;
      if (!skipScroll) {
        window.scrollBy(0, 0 - tocHeight);
      }
      tocNav.focus();
      sidebarMedia.addListener(autoToggle); // auto-collapse when out of ro=
om
    }
    else {
      document.body.classList.add('toc-inline');
      document.body.classList.remove('toc-sidebar');
      toggle.innerHTML =3D expandSidebarText;
      if (!skipScroll) {
        window.scrollBy(0, tocNav.offsetHeight);
      }
      if (toggle.matches(':hover')) {
        /* Unfocus button when not using keyboard navigation,
           because I don=E2=80=99t know where else to send the focus. */
        toggle.blur();
      }
    }
  }

  function createSidebarToggle() {
    /* Create the sidebar toggle in JS; it shouldn=E2=80=99t exist when JS =
is off. */
    var toggle =3D document.createElement('a');
      /* This should probably be a button, but appearance isn=E2=80=99t sta=
ndards-track.*/
    toggle.id =3D 'toc-toggle';
    toggle.class =3D 'toc-toggle';
    toggle.href =3D '#toc';
    toggle.innerHTML =3D collapseSidebarText;

    sidebarMedia.addListener(autoToggle);
    var toggler =3D function(e) {
      e.preventDefault();
      sidebarMedia.removeListener(autoToggle); // persist explicit off stat=
es
      toggleSidebar();
      return false;
    }
    toggle.addEventListener('click', toggler, false);


    /* Get <nav id=3Dtoc-nav>, or make it if we don=E2=80=99t have one. */
    var tocNav =3D document.getElementById('toc-nav');
    if (!tocNav) {
      tocNav =3D document.createElement('p');
      tocNav.id =3D 'toc-nav';
      /* Prepend for better keyboard navigation */
      document.body.insertBefore(tocNav, document.body.firstChild);
    }
    /* While we=E2=80=99re at it, make sure we have a Jump to Toc link. */
    var tocJump =3D document.getElementById('toc-jump');
    if (!tocJump) {
      tocJump =3D document.createElement('a');
      tocJump.id =3D 'toc-jump';
      tocJump.href =3D '#toc';
      tocJump.innerHTML =3D tocJumpText;
      tocNav.appendChild(tocJump);
    }

    tocNav.appendChild(toggle);
  }

  var toc =3D 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() =3D=3D "a" && document.body.classLi=
st.contains('toc-sidebar') && !sidebarMedia.matches) {
        toggleSidebar(false);
      }
    }, false);
  }
  else {
    console.warn("Can=E2=80=99t find Table of Contents. Please use <nav id=
=3D'toc'> around the ToC.");
  }

  /* Wrap tables in case they overflow */
  var tables =3D document.querySelectorAll(':not(.overlarge) > table.data, =
:not(.overlarge) > table.index');
  var numTables =3D tables.length;
  for (var i =3D 0; i < numTables; i++) {
    var table =3D tables[i];
    var wrapper =3D document.createElement('div');
    wrapper.className =3D 'overlarge';
    table.parentNode.insertBefore(wrapper, table);
    wrapper.appendChild(table);
  }

})();
</script>
  <h2 class=3D"no-num no-ref heading settled" id=3D"references"><span class=
=3D"content">References</span><a class=3D"self-link" href=3D"#references"><=
/a></h2>
  <h3 class=3D"no-num no-ref heading settled" id=3D"informative"><span clas=
s=3D"content">Informative References</span><a class=3D"self-link" href=3D"#=
informative"></a></h3>
  <dl>
   <dt id=3D"biblio-aws">[AWS]
   <dd><a href=3D"https://github.com/aws/aws-sdk-cpp/issues/847">Use const =
references to extend lifetime of temporaries</a>. April 2018. URL: <a href=
=3D"https://github.com/aws/aws-sdk-cpp/issues/847">https://github.com/aws/a=
ws-sdk-cpp/issues/847</a>
   <dt id=3D"biblio-chromium">[Chromium]
   <dd><a href=3D"https://bugs.chromium.org/p/chromium/issues/detail?id=3D8=
32211">clean up and enable Wreturn-std-move</a>. April 2018. URL: <a href=
=3D"https://bugs.chromium.org/p/chromium/issues/detail?id=3D832211">https:/=
/bugs.chromium.org/p/chromium/issues/detail?id=3D832211</a>
   <dt id=3D"biblio-cwg1579">[CWG1579]
   <dd>Jeffrey Yasskin. <a href=3D"http://open-std.org/JTC1/SC22/WG21/docs/=
cwg_defects.html#1579">Return by converting move constructor</a>. October 2=
012. URL: <a href=3D"http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.ht=
ml#1579">http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#1579</a>
   <dt id=3D"biblio-d43322">[D43322]
   <dd>Arthur O'Dwyer. <a href=3D"https://reviews.llvm.org/D43322">Diagnose=
 cases of 'return x' that should be 'return std::move(x)' for efficiency</a=
>. February 2018. URL: <a href=3D"https://reviews.llvm.org/D43322">https://=
reviews.llvm.org/D43322</a>
   <dt id=3D"biblio-folly">[Folly]
   <dd><a href=3D"https://github.com/facebook/folly/commit/b5105fc5581eef1a=
f2a809b7a3a50ac820e572ae">fix -Wreturn-std-move errors</a>. April 2018. URL=
: <a href=3D"https://github.com/facebook/folly/commit/b5105fc5581eef1af2a80=
9b7a3a50ac820e572ae">https://github.com/facebook/folly/commit/b5105fc5581ee=
f1af2a809b7a3a50ac820e572ae</a>
   <dt id=3D"biblio-khronos">[Khronos]
   <dd><a href=3D"https://github.com/KhronosGroup/SPIRV-Tools/issues/1521">=
Use std::move(str) suggested with -Wreturn-std-move</a>. April 2018. URL: <=
a href=3D"https://github.com/KhronosGroup/SPIRV-Tools/issues/1521">https://=
github.com/KhronosGroup/SPIRV-Tools/issues/1521</a>
   <dt id=3D"biblio-libreoffice">[LibreOffice]
   <dd>Stephan Bergmann. <a href=3D"https://cgit.freedesktop.org/libreoffic=
e/core/commit/?id=3D74b6e61dde64c5e24bffacda6f67dbf3d1fc7032">-Werror,-Wret=
urn-std-move (recent Clang trunk)</a>. April 2018. URL: <a href=3D"https://=
cgit.freedesktop.org/libreoffice/core/commit/?id=3D74b6e61dde64c5e24bffacda=
6f67dbf3d1fc7032">https://cgit.freedesktop.org/libreoffice/core/commit/?id=
=3D74b6e61dde64c5e24bffacda6f67dbf3d1fc7032</a>
   <dt id=3D"biblio-mozilla">[Mozilla]
   <dd><a href=3D"https://bugzilla.mozilla.org/show_bug.cgi?id=3D1454848">V=
arious '-Wreturn-std-move' build warnings with clang 7.0 (trunk), for cases=
 where return invokes (cheap) string copy-constructor rather than move cons=
tructor</a>. April 2018. URL: <a href=3D"https://bugzilla.mozilla.org/show_=
bug.cgi?id=3D1454848">https://bugzilla.mozilla.org/show_bug.cgi?id=3D145484=
8</a>
   <dt id=3D"biblio-p0527">[P0527]
   <dd>David Stone. <a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/=
papers/2018/p0527r1.html">Implicitly move from rvalue references in return =
statements</a>. November 2017. URL: <a href=3D"http://www.open-std.org/jtc1=
/sc22/wg21/docs/papers/2018/p0527r1.html">http://www.open-std.org/jtc1/sc22=
/wg21/docs/papers/2018/p0527r1.html</a>
   <dt id=3D"biblio-revzin">[Revzin]
   <dd>Barry Revzin; Howard Hinnant; Arthur O'Dwyer. <a href=3D"https://gro=
ups.google.com/a/isocpp.org/d/msg/std-proposals/eeLS8vI05nM/_BP-8YTPDAAJ">s=
td-proposals thread: By-value sinks</a>. August 2018. URL: <a href=3D"https=
://groups.google.com/a/isocpp.org/d/msg/std-proposals/eeLS8vI05nM/_BP-8YTPD=
AAJ">https://groups.google.com/a/isocpp.org/d/msg/std-proposals/eeLS8vI05nM=
/_BP-8YTPDAAJ</a>
   <dt id=3D"biblio-sg14">[SG14]
   <dd>Arthur O'Dwyer. <a href=3D"https://github.com/WG21-SG14/SG14/issues/=
125">inplace_function implicit conversion chooses copy over move</a>. Febru=
ary 2018. URL: <a href=3D"https://github.com/WG21-SG14/SG14/issues/125">htt=
ps://github.com/WG21-SG14/SG14/issues/125</a>
  </dl>
------=_Part_157_732471800.1534376822752--

.


Author: Barry Revzin <barry.revzin@gmail.com>
Date: Wed, 15 Aug 2018 17:34:12 -0700 (PDT)
Raw View
------=_Part_152_405476102.1534379653153
Content-Type: multipart/alternative;
 boundary="----=_Part_153_590920392.1534379653153"

------=_Part_153_590920392.1534379653153
Content-Type: text/plain; charset="UTF-8"

On Wednesday, August 15, 2018 at 6:47:02 PM UTC-5, Arthur O'Dwyer wrote:
>
> I'm attaching a new draft revision of D1155 "More implicit moves."
>

Looks great to me!

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/c665bd34-9518-4a4a-ac95-b5a3d873f1dc%40isocpp.org.

------=_Part_153_590920392.1534379653153
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Wednesday, August 15, 2018 at 6:47:02 PM UTC-5, Arthur =
O&#39;Dwyer wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"=
ltr"><div>I&#39;m attaching a new draft revision of D1155 &quot;More implic=
it moves.&quot;=C2=A0=C2=A0<br></div></div></blockquote><div><br></div><div=
>Looks great to me!</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/c665bd34-9518-4a4a-ac95-b5a3d873f1dc%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/c665bd34-9518-4a4a-ac95-b5a3d873f1dc=
%40isocpp.org</a>.<br />

------=_Part_153_590920392.1534379653153--

------=_Part_152_405476102.1534379653153--

.