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 />
<br />
<br />
<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"><<a href=3D"mailto:hive=
master@hotmail.de" target=3D"_blank">hivemaster@hotmail.de</a>></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'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'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'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;:-)" Liber=A0 <mailto:<a href=3D"mailto:nevin@eviloverlord.com"=
target=3D"_blank">nevin@eviloverlord.com</a>>=A0 (847) 691-1404<br>
<p></p>
-- <br />
<br />
<br />
<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 />
<br />
<br />
<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"> - 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> Will do, thanks!<br></div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_2422_29928583.1353047336917--
.