Topic: Relaxing automatic move restrictions


Author: Xeo <hivemaster@hotmail.de>
Date: Thu, 15 Nov 2012 18:48:15 -0800 (PST)
Raw View
------=_Part_32_19094462.1353034095858
Content-Type: multipart/alternative;
 boundary="----=_Part_33_6048203.1353034095858"

------=_Part_33_6048203.1353034095858
Content-Type: text/plain; charset=ISO-8859-1

It's been an annoyance for me that not all local variables are moved, so I
came up with this proposal.
Attached is the raw .txt. form without any styling what-so-ever, I hope
it's still readable.

Feedback welcome.

--




------=_Part_33_6048203.1353034095858
Content-Type: text/html; charset=ISO-8859-1

It's been an annoyance for me that not all local variables are moved, so I came up with this proposal.<br>Attached is the raw .txt. form without any styling what-so-ever, I hope it's still readable.<br><br>Feedback welcome.<br>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_33_6048203.1353034095858--
------=_Part_32_19094462.1353034095858
Content-Type: text/plain; charset=UTF-8; name=relaxed_automatic_moves.txt
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment; filename=relaxed_automatic_moves.txt
X-Attachment-Id: 5a67483e-b271-4ee7-bff6-341541c296dd

Document number: =09not allocated
Date: =092012-11-16
Project: =09Programming Language C++, Core Working Group
Reply-to: =09hivemaster at hotmail dot de

Relaxing restrictions on automatic moves

-- Introduction

Automatic moves currently depend on the rules of copy-elision (with the exc=
eption that function parameters are also allowed as the source) and will on=
ly be applied if copy-elision for some reason does not happen (through bran=
ches, for example).
This seems overly restrictive, as it does not allow automatic moves of subo=
bjects or variables of types that differ from the return type of the functi=
on. This proposal aims to relax these restrictions.

-- Motivation and Scope

Currently, users need to think whether they should or should not wrap a ret=
urned local variable in `std::move`, in fear of either inhibiting RVO or no=
t getting a move that might be expected.

-- Impact on the Standard

12.8 [class.copy] p32 will need to be rewritten.

-- Impact on existing code

Cases where a class-type is copyable but not movable (private / deleted mov=
e constructor) and the author of a function relied on not getting an automa=
tic move will break, although it's a hard error and not a silent one. Howev=
er, I expect this to be a non-issue as such a class-type makes little sens,=
 if any (atleast to me).

VI. Technical Specifications

- Change 12.8 [class.copy] p32 to:

When
  - the criteria for copy-elision are met or would be met save for the fact=
 that the source object is a function parameter, and the object to be copie=
d is designated by an lvalue, or
  - the criteria for copy-elision are not met and the expression is the nam=
e of a non-volatile automatic object or a subobject thereof=E2=80=A0

overload resolution to select the constructor for the copy is first perform=
ed as if the object were designated by an rvalue. If overload resolution fa=
ils, or if the type of the first parameter of the selected constructor is n=
ot an rvalue reference to the object=E2=80=99s type (possibly cv-qualified)=
, overload resolution is performed again, considering the object as an lval=
ue. [ Note: This two-stage overload resolution must be performed regardless=
 of whether copy elision will occur. It determines the constructor to be ca=
lled if elision is not performed, and the selected constructor must be acce=
ssible even if the call is elided. =E2=80=94end note ]

- Add a footnote:

=E2=80=A0 The intent is to always move (sub)objects that are about to go ou=
t of scope.

- Add to the examples:

class Member{
public:
  Member(Member&&);
private:
  Member(const Member&&);
};

// extend Thing
class Thing{
  // ...
public:
  Member m;
};

class Other{
public:
  Other(Thing&&);
  Other(Member&&)
private:
  Other(const Thing&);
  Other(const Member&);
};

Other h(bool b){
  Thing t;
  if (b)
    return t; // OK: Other(Thing&&) used to construct return value
  else
    return t.m; // OK: Other(Member&&) used to construct return value
}
------=_Part_32_19094462.1353034095858--

.


Author: Nevin Liber <nevin@eviloverlord.com>
Date: Thu, 15 Nov 2012 21:08:37 -0600
Raw View
--0015174bddc6f4870704ce942cf4
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

On 15 November 2012 20:48, Xeo <hivemaster@hotmail.de> wrote:

> It's been an annoyance for me that not all local variables are moved, so =
I
> came up with this proposal.
> Attached is the raw .txt. form without any styling what-so-ever, I hope
> it's still readable.
>
> Feedback welcome.
>
> Cases where a class-type is copyable but not movable (private / deleted m=
ove constructor) and the author of a function relied on not getting an auto=
matic move will break, although it's a hard error and not a silent one. How=
ever, I expect this to be a non-issue as such a class-type makes little sen=
s, if any (atleast to me).
>
>
That basically breaks all C++03 classes with a user defined copy
constructor.
--=20
 Nevin ":-)" Liber  <mailto:nevin@eviloverlord.com>  (847) 691-1404

--=20




--0015174bddc6f4870704ce942cf4
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

On 15 November 2012 20:48, Xeo <span dir=3D"ltr">&lt;<a href=3D"mailto:hive=
master@hotmail.de" target=3D"_blank">hivemaster@hotmail.de</a>&gt;</span> w=
rote:<br><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=
=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

It&#39;s been an annoyance for me that not all local variables are moved, s=
o I came up with this proposal.<br>Attached is the raw .txt. form without a=
ny styling what-so-ever, I hope it&#39;s still readable.<br><br>Feedback we=
lcome.<span class=3D"HOEnZb"><font color=3D"#888888"><br>



<p></p></font><pre style=3D"word-wrap:break-word;white-space:pre-wrap">Case=
s where a class-type is copyable but not movable (private / deleted move co=
nstructor) and the author of a function relied on not getting an automatic =
move will break, although it&#39;s a hard error and not a silent one. Howev=
er, I expect this to be a non-issue as such a class-type makes little sens,=
 if any (atleast to me).</pre>

</span></blockquote><div><br></div><div>That basically breaks all C++03 cla=
sses with a user defined copy constructor.=A0</div></div>-- <br>=A0Nevin &q=
uot;:-)&quot; Liber=A0 &lt;mailto:<a href=3D"mailto:nevin@eviloverlord.com"=
 target=3D"_blank">nevin@eviloverlord.com</a>&gt;=A0 (847) 691-1404<br>


<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

--0015174bddc6f4870704ce942cf4--

.


Author: Xeo <hivemaster@hotmail.de>
Date: Thu, 15 Nov 2012 19:41:17 -0800 (PST)
Raw View
------=_Part_51_21466218.1353037277892
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

On Friday, November 16, 2012 4:15:14 AM UTC+1, Nevin ":-)" Liber wrote:

> That basically breaks all C++03 classes with a user defined copy=20
> constructor.
>

How so? Under current rules, a move constructor will only be implicitly=20
declared as defaulted if all conditions under =A712.8/9 apply, nothing=20
happens otherwise. The note even says:

[ *Note:* When the move constructor is not implicitly declared or=20
> explicitly supplied, expressions that otherwise
> would have invoked the move constructor may instead invoke a copy=20
> constructor. *=97end note* ]
>

--=20




------=_Part_51_21466218.1353037277892
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

On Friday, November 16, 2012 4:15:14 AM UTC+1, Nevin ":-)" Liber wrote:<br>=
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;"><div class=3D"gmail_quote"><di=
v>That basically breaks all C++03 classes with a user defined copy construc=
tor.<br></div></div></blockquote><div><br>How so? Under current rules, a mo=
ve constructor will only be implicitly declared as defaulted if all conditi=
ons under =A712.8/9 apply, nothing happens otherwise. The note even says:<b=
r><br><blockquote style=3D"margin: 0px 0px 0px 0.8ex; border-left: 1px soli=
d rgb(204, 204, 204); padding-left: 1ex;" class=3D"gmail_quote">[ <i>Note:<=
/i> When the move constructor is not implicitly declared or explicitly supp=
lied, expressions that otherwise<br>would have invoked the move constructor=
 may instead invoke a copy constructor. <i>=97end note</i> ]<br></blockquot=
e></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_51_21466218.1353037277892--

.


Author: Richard Smith <richard@metafoo.co.uk>
Date: Thu, 15 Nov 2012 22:01:38 -0800
Raw View
On Thu, Nov 15, 2012 at 6:48 PM, Xeo <hivemaster@hotmail.de> wrote:
> It's been an annoyance for me that not all local variables are moved, so I
> came up with this proposal.
> Attached is the raw .txt. form without any styling what-so-ever, I hope it's
> still readable.

I think the intent of this change is a good idea, but the proposed
wording doesn't work. Your wording applies to all variables, whether
or not they are about to go out of scope. Also, you need something a
bit like p31's that the expression is just the name of the variable
(and not some expression involving it), or you'll break code like:

  std::string f(std::string s) {
    return s + s; // can't treat 's' as an xvalue here
  }

You could require that the variable appear only once in the
expression, except that would require significant lookahead.

These rules need refactoring anyway (see core issue 1493) -- defining
the automatic move rules in terms of the copy elision rules doesn't
really work very well. I would suggest you directly contact Mike
Miller and see if he'll open a core issue for this.

--




.


Author: Xeo <hivemaster@hotmail.de>
Date: Thu, 15 Nov 2012 22:28:56 -0800 (PST)
Raw View
------=_Part_2422_29928583.1353047336917
Content-Type: text/plain; charset=ISO-8859-1



On Friday, November 16, 2012 7:01:40 AM UTC+1, Richard Smith wrote:

> Also, you need something a
>
bit like p31's that the expression is just the name of the variable
> (and not some expression involving it), or you'll break code like:
>

I specifically have that (second bullet point):

>  - the criteria for copy-elision are not met and the expression is the
> name of a non-volatile automatic object or a subobject thereof
>

In fact, I copied that bit straight from p31 and added the subobject part.
:)

These rules need refactoring anyway (see core issue 1493) -- defining
> the automatic move rules in terms of the copy elision rules doesn't
> really work very well. I would suggest you directly contact Mike
> Miller and see if he'll open a core issue for this.
>
 Will do, thanks!

--




------=_Part_2422_29928583.1353047336917
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<br><br>On Friday, November 16, 2012 7:01:40 AM UTC+1, Richard Smith wrote:=
<br><blockquote style=3D"margin: 0px 0px 0px 0.8ex; border-left: 1px solid =
rgb(204, 204, 204); padding-left: 1ex;" class=3D"gmail_quote">Also, you nee=
d something a
<br></blockquote><blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">bit like p31'=
s that the expression is just the name of the variable
<br>(and not some expression involving it), or you'll break code like:
<br></blockquote><div><br>I specifically have that (second bullet point):<b=
r><blockquote style=3D"margin: 0px 0px 0px 0.8ex; border-left: 1px solid rg=
b(204, 204, 204); padding-left: 1ex;" class=3D"gmail_quote">&nbsp;- the cri=
teria for copy-elision are not met and the expression is the name of a non-=
volatile automatic object or a subobject thereof<br></blockquote><br>In fac=
t, I copied that bit straight from p31 and added the subobject part. :)<br>=
<br> </div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left=
: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">These rules need re=
factoring anyway (see core issue 1493) -- defining
<br>the automatic move rules in terms of the copy elision rules doesn't
<br>really work very well. I would suggest you directly contact Mike
<br>Miller and see if he'll open a core issue for this.
<br></blockquote><div>&nbsp;Will do, thanks!<br></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_2422_29928583.1353047336917--

.