220 25490 <d67f8331-d920-415d-8f71-0af7397dd2c6@isocpp.org> article
Path: news.gmane.org!not-for-mail
From: Nicol Bolas <jmckesson@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Re: Relocation as a solution for the valueless
 variant problem?
Date: Sun, 10 Apr 2016 11:07:38 -0700 (PDT)
Lines: 465
Approved: news@gmane.org
Message-ID: <d67f8331-d920-415d-8f71-0af7397dd2c6@isocpp.org>
References: <b4feb52d-4cd0-475f-9f3d-6694564bc1b0@isocpp.org>
 <4187538d-68fa-4582-ba26-f406479abe67@isocpp.org>
 <eafd831f-85d2-430c-9969-7d084e6d28d2@isocpp.org>
 <CALQmNFggBQSADjEqS7pEzcdPSStGJfXkJdX0d2CwW_TmwqA=yQ@mail.gmail.com>
 <105d82bc-e1cf-4795-894c-112cd591c3af@isocpp.org>
 <CALQmNFja3Kt1XRR8S7Qr3rOktChVzuDGO7ZtSaQpsWaohU6wAA@mail.gmail.com>
 <4f31b957-05be-47cf-a1ca-03f33a9900c0@isocpp.org>
 <CALQmNFgoV-Rg4T6+KqMFt6vNa7GCDpU=jVLRcnK4dDd+eBby8A@mail.gmail.com>
 <30181f63-7189-494d-9294-3f8b8759308f@isocpp.org>
 <d7eee27f-bdfc-45b0-9c29-508dd01975b3@isocpp.org>
 <cad96977-d5d4-4eea-8169-ae1ceb8b6477@isocpp.org>
 <456f6164-031c-4ccc-ba25-39fcb5714b98@isocpp.org>
 <96061c41-6f44-468b-b5ec-fb1fd6fad4b7@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_1170_2059248401.1460311658407"
X-Trace: ger.gmane.org 1460311663 13775 80.91.229.3 (10 Apr 2016 18:07:43 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Sun, 10 Apr 2016 18:07:43 +0000 (UTC)
Cc: isocppgroup@denisbider.com, barry.revzin@gmail.com
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBCEKFTV6ZUMBB25MVK4AKGQEEQGOTVI@isocpp.org Sun Apr 10 20:07:42 2016
Return-path: <std-proposals+bncBCEKFTV6ZUMBB25MVK4AKGQEEQGOTVI@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-ob0-f200.google.com ([209.85.214.200])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBCEKFTV6ZUMBB25MVK4AKGQEEQGOTVI@isocpp.org>)
	id 1apJlt-0000CV-Pr
	for gclcip-std-proposals@m.gmane.org; Sun, 10 Apr 2016 20:07:42 +0200
Original-Received: by mail-ob0-f200.google.com with SMTP id th5sf213133932obc.1
        for <gclcip-std-proposals@m.gmane.org>; Sun, 10 Apr 2016 11:07:41 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=date:from:to:cc:message-id:in-reply-to:references:subject
         :mime-version:x-original-sender:reply-to:precedence:mailing-list
         :list-id:x-spam-checked-in-group:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=b7C5l2x221Z1wjA3YsYK8KIIAgqHwjN1Z8d+yZFbRig=;
        b=o4MlrW56pdjqixxWNmplhKIKd7Dyy76RfztXhGUyTcASbC6rqlPPpoDGQkbQWEduNx
         RW4FQtwz2/uRSSTFlo1twmUMalP1eEAcbFNLj5CT8hPROFf3K5bf1ls/bLs1vSs6YhPL
         Rif5sv2RE6PhzBvKVFPWHHDfU8RVd8wyHqOHnO4UilI4w4ncAdKOWJexub5RqJ7eYMjS
         O0roVVJaNPAR2t6kBNMEVmmlD8Z4lXodpuXp8GOMozDPDBWLDtaBSBA3RZpQ/Y/C0BSA
         kup+adVI6RR1aSxRDaadNeDO9QDtfSEmhHd2FF+mG7n5I9dgaFb2U1mGipCPzk0ToYpB
         ZFew==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20120113;
        h=date:from:to:cc:message-id:in-reply-to:references:subject
         :mime-version:x-original-sender:reply-to:precedence:mailing-list
         :list-id:x-spam-checked-in-group:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=b7C5l2x221Z1wjA3YsYK8KIIAgqHwjN1Z8d+yZFbRig=;
        b=FiFsH7LnkyKqjD/GTumx5DGrnr/bKp6dOxNHj3nizjh2/1EkZ8fZFnYseRHCeDoJq2
         /0kcGOPQa9SWZd4bIgidYdlo23MwonDiMPavR2ZkvxZgkTsNh0S+Ff6b2Xw1DDA57r3n
         +W68jAMt8HlCuTZgG7XNjRqxXhV2naAhJCBGrHK8nZHdOQjaCf97fXRhmGWxRvljaWCF
         qfnKDMldm5nveqvd5vFZkbDP5rXW4FMHtDekFWNpwR9iPe3KXrMwkNvtvZ33HJHaavgY
         pBqgPTbMv+/5X/Ysc/ujVMZLnk6WE5/b9LLYB9kR1Ltx4eslmHi7nSSYLz2a4tHO34af
         HWKw==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:date:from:to:cc:message-id:in-reply-to
         :references:subject:mime-version:x-original-sender:reply-to
         :precedence:mailing-list:list-id:x-spam-checked-in-group:list-post
         :list-help:list-archive:list-subscribe:list-unsubscribe;
        bh=b7C5l2x221Z1wjA3YsYK8KIIAgqHwjN1Z8d+yZFbRig=;
        b=Y/qyV/UozXtpQop13MTFVhO3n++dbuvRqsrcN1Mt8RUczIB26Emk/mvVPMFWmIF+XB
         1IA0dP0dbOZvNQ/Rq/nFGDAJ23WbeJWVLtV9Z5P1xEmIoQPCj8cl+KIsi6grrUL62tim
         cwyVuwXVORfWIza2/z6q1F3yKoLe3AcZi5dgkYuA5kbp0fCMnlW1U+0X7Rdsf80bG933
         UQfGX6AV+PncB0bBPhQxVnJV3P4Tto5T2wOOw2eDWsyeD3yz8LjUpCfFowFVqpeOLxkw
         +CLfZwNLbEhv5kK8N/o/DehrHmqCU9GBJt47YokZHFUYGS9RXY43hFJi9wX1y3HWM69h
         7XGA==
X-Gm-Message-State: AD7BkJKle7v+uCoNizpqfSu04+1JbrmW5j1UxVDYypNOjgAKs8CDkf94gNArU/jqwEpt3g==
X-Received: by 10.50.171.137 with SMTP id au9mr9023500igc.7.1460311660720;
        Sun, 10 Apr 2016 11:07:40 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.107.8.26 with SMTP id 26ls1741802ioi.9.gmail; Sun, 10 Apr 2016
 11:07:39 -0700 (PDT)
X-Received: by 10.50.47.39 with SMTP id a7mr247638ign.2.1460311659696;
        Sun, 10 Apr 2016 11:07:39 -0700 (PDT)
In-Reply-To: <96061c41-6f44-468b-b5ec-fb1fd6fad4b7@isocpp.org>
X-Original-Sender: jmckesson@gmail.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Spam-Checked-In-Group: std-proposals@isocpp.org
X-Google-Group-Id: 399137483710
List-Post: <https://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <https://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <https://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>,
 <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:25490
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/25490>

------=_Part_1170_2059248401.1460311658407
Content-Type: multipart/alternative; 
	boundary="----=_Part_1171_706801045.1460311658418"

------=_Part_1171_706801045.1460311658418
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Friday, April 8, 2016 at 5:44:24 PM UTC-4, isocp...@denisbider.com wrote=
:
>
> You are quite correct. This aspect is being implied, rather than being=20
> addressed.
>

No, they are not implied. The term "implied" would suggest that there would=
=20
be even a cursory mention of something approaching this notion somewhere in=
=20
the proposal. Nothing of the like was mentioned by any of the text in that=
=20
document. Therefore, the correct term would seem to be "assumed", not=20
"implied".

But in either case, proposals should not have vital features be "implied".=
=20
Proposals, *especially* for exceedingly complex ones like yours, need to=20
actually state what the whole feature is, as clearly as possible. Formal=20
wording isn't necessary (at first), but vital elements of the feature need=
=20
something more than mere implication.

I am toying with the following text - currently rather informal:
>
> "Move optimization=20
>
> When a type is relocatable; then in situations where an implementation=20
> would otherwise move an object value to an object of same type by invokin=
g=20
> a move constructor, followed by destruction of the moved-from object; and=
=20
> where no use of the moved-from object occurs between move and destruction=
;=20
> the implementation may instead invoke the type=E2=80=99s relocator, elidi=
ng the=20
> move constructor and destructor.
> This move optimization *must* occur when move construction followed by=20
> destruction would otherwise be used when returning a relocatable type by=
=20
> value from a function, into a new object of same type."
>
> =20
> This would require relocation for return by value, if relocation is=20
> available and copy elision isn't. This would be similar to how move vs.=
=20
> copy construction is already chosen right now.=20
> =20
> It would also open the door for a compiler to detect when an object is=20
> being moved to a new location, followed by destruction in the previous=20
> location. In this case, the compiler *could* use relocation (move=20
> destruction), but is not forced to.
> =20
> An open concern here is whether this would be, in practice, too subtle.=
=20
> For example, a developer might want to ensure that relocation is used,=20
> instead of move construction + destruction:
>
=20
>
std::unique_ptr<Thing> MakeThing() {
>   std::list<int> lst =3D ...;
>   InitializeList(lst);
>   return std::make_unique<Thing>(std::move(lst));
>     // Is this copy construction, move construction, or relocation?}
>
> =20
> On the one hand, currently, we do not have syntax that the developer coul=
d=20
> use to ensure move construction is used, rather than copy construction.
>

No, but we have an assurance that if `Thing` is moveable, then it will use=
=20
move construction. That's all that is necessary. Remember: movement is an=
=20
*optimization* of copying. So if the author of `Thing` has decided that his=
=20
type will not benefit from a move constructor, then that's up to him and=20
the needs of `Thing`. For users of that type, we assume that we will get=20
the most efficient operation available for that type.

Or to put it another way, you shouldn't *care* if it's really doing a move=
=20
or a copy. You're simply giving the object the opportunity to make the=20
operation efficient.

The fundamental difference between movement and destructive move is that it=
=20
is two operations in one. It's a move followed by an ending of the lifetime=
=20
of the object. You can't ignore or postpone that destruction. It's not=20
merely an optimized move. It is a fundamentally different type of operation=
..

Therefore, if you ask for destructive move on a variable, you *must get it*=
..=20
That is, every type must be destructive moveable, even if that operation=20
will simply perform a move/copy followed by a destructor call. The only=20
types that are not destructive moveable are those types which are not=20
move/copyable at all.

Move is an optimized copy. Destructive move is an optimization as well. But=
=20
it's an optimization of an operation that current does not exist in C++. So=
=20
your idea is really 2 things:

1. Adding destructive movement as an operation which the user can invoke.=
=20
This also includes identifying all of the places where destructive movement=
=20
can be invoked automatically by the compiler.

2. Adding the ability to write specialized destructive move code on a=20
per-object basis. This also needs to include issues (which your paper=20
didn't handle) about the *order* of the destruction of member elements. C++=
=20
has a well-defined order that member subobjects are supposed to be=20
destroyed in. A destructor cannot interfere in that order. So neither=20
should a destructive move operation. Your example in your initial proposal=
=20
showed cases where you change the order of member subobject destruction.

The developer just has to use syntax that allows for move construction, and=
=20
> then count on that a move constructor is available.
> =20
> Suppose that we have relocation, and the compiler has determined to use=
=20
> relocation in the above example.
> =20
> Then, someone modifies the above function as follows:
> =20
>
> std::unique_ptr<Thing> MakeThing() {
>   std::list<int> lst =3D ...;
>   InitializeList(lst);
>   auto thing =3D std::make_unique<Thing>(std::move(lst));
>   ReuseListForOtherPurpose(lst);
>   return thing;}
>
> =20
> Now, this definitely no longer uses relocation, because *lst* is=20
> being used again.
>
> Is this a concern? How do we prevent this?
>
> To avoid introducing a keyword, one way could be to add a blessed standar=
d=20
> library function, say *std::final_reference*:=20
>
> std::unique_ptr<Thing> MakeThing() {
>   std::list<int> lst =3D ...;
>   InitializeList(lst);
>   auto thing =3D std::make_unique<Thing>(std::final_reference(lst));
>   ReuseListForOtherPurpose(lst);  // Error: use of "lst" after final_refe=
rence
>   return thing;}
>
>
> This would require a compiler to detect the reuse of "lst" after it's use=
d=20
> in *std::final_reference*, and flag an error when "lst" is reused.
>
> An alternative to a blessed function would be a new keyword, e.g.=20
> "final_reference".=20
>

> Thoughts? Ideas?
>

This is one of the big problems with destructive move as a concept.

When you explicitly invoke a destructive move, you are destroying the=20
object. But we normally don't allow you to directly destroy automatic=20
variables. Because the compiler is going to destroy them later. Permitting=
=20
the user to destroy automatic variables can get into all kinds of problems.

What if you invoke the destructive move on the variable conditionally? Does=
=20
the compiler need to keep around a hidden boolean variable to know if the=
=20
automatic variable has been destroyed? What if you invoke it as part of a=
=20
long expression, and C++'s undefined order of expression evaluation starts=
=20
getting in the way? And so forth.

Whether it's done by some standard library function or a language keyword,=
=20
these problems persist.

This is one of the reasons why you need to do more research on this topic.=
=20
This stuff has been discussed at length, and these issues (among others)=20
have been brought up before.

--=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/d67f8331-d920-415d-8f71-0af7397dd2c6%40isocpp.or=
g.

------=_Part_1171_706801045.1460311658418
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Friday, April 8, 2016 at 5:44:24 PM UTC-4, isocp...@den=
isbider.com 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>You are quite correct.=C2=A0This aspect is being implied, rather =
than being addressed.</div></div></blockquote><div><br>No, they are not imp=
lied. The term &quot;implied&quot; would suggest that there would be even a=
 cursory mention of something approaching this notion somewhere in the prop=
osal. Nothing of the like was mentioned by any of the text in that document=
.. Therefore, the correct term would seem to be &quot;assumed&quot;, not &qu=
ot;implied&quot;.<br><br>But in either case, proposals should not have vita=
l features be &quot;implied&quot;. Proposals, <i>especially</i> for exceedi=
ngly complex ones like yours, need to actually state what the whole feature=
 is, as clearly as possible. Formal wording isn&#39;t necessary (at first),=
 but vital elements of the feature need something more than mere implicatio=
n.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"lt=
r"><div><div></div></div><div>I am toying with the following text - current=
ly rather informal:</div><blockquote><h2 style=3D"margin:12pt 0in 0pt"><fon=
t face=3D"Calibri Light" size=3D"4" color=3D"#2e74b5">&quot;Move optimizati=
on</font></h2><font face=3D"Times New Roman" size=3D"3" color=3D"#000000">

</font><p style=3D"margin:8pt 0in;text-align:justify"><font face=3D"Calibri=
" size=3D"3" color=3D"#000000">When a type is relocatable; then
in situations where an implementation would otherwise move an object value =
to
an object of same type by invoking a move constructor, followed by destruct=
ion
of the moved-from object; and where no use of the moved-from object occurs =
between
move and destruction; the implementation may instead invoke the type=E2=80=
=99s relocator,
eliding the move constructor and destructor.</font></p><font color=3D"#0000=
00"><font face=3D"Times New Roman" size=3D"3">

</font><span style=3D"line-height:107%;font-family:&quot;Calibri&quot;,sans=
-serif;font-size:11pt">This move optimization <b>must</b> occur when move c=
onstruction followed by destruction would otherwise
be used when returning a relocatable type by value from a function, into a =
new object
of same type.&quot;</span></font></blockquote><div>=C2=A0</div><div>This wo=
uld require relocation for return by value, if relocation is available and =
copy elision isn&#39;t. This would be similar to how move vs. copy construc=
tion is already chosen right now. </div><div><div>=C2=A0</div></div><div>It=
 would also open the door for a compiler to detect when an object is being =
moved to a new location, followed by destruction in the previous location.=
=C2=A0In this case, the compiler <i>could</i>=C2=A0use relocation (move des=
truction), but is not forced to.</div><div><div>=C2=A0</div></div><div>An o=
pen concern here is whether this would be, in practice, too subtle. For exa=
mple, a developer might want to ensure that relocation is used, instead of =
move construction + destruction:</div></div></blockquote><blockquote style=
=3D"margin: 0px 0px 0px 0.8ex; border-left: 1px solid rgb(204, 204, 204); p=
adding-left: 1ex;" class=3D"gmail_quote"><div>=C2=A0</div></blockquote><blo=
ckquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-=
left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><pre style=
=3D"background:rgb(246,248,255);color:rgb(0,0,32)"><span style=3D"color:rgb=
(89,89,121)"><pre style=3D"background:rgb(246,248,255);color:rgb(0,0,32)"><=
span style=3D"color:rgb(0,102,238)">std</span><span style=3D"color:rgb(64,9=
6,128)">::</span><span style=3D"color:rgb(0,48,96)">unique_ptr</span><span =
style=3D"color:rgb(64,96,128)">&lt;</span>Thing<span style=3D"color:rgb(64,=
96,128)">&gt;</span> MakeThing<span style=3D"color:rgb(48,128,128)">(</span=
><span style=3D"color:rgb(48,128,128)">)</span> <span style=3D"color:rgb(64=
,96,128)">{</span>
  <span style=3D"color:rgb(0,102,238)">std</span><span style=3D"color:rgb(6=
4,96,128)">::</span><span style=3D"color:rgb(0,48,96)">list</span><span sty=
le=3D"color:rgb(64,96,128)">&lt;</span><span style=3D"color:rgb(32,0,128);f=
ont-weight:bold">int</span><span style=3D"color:rgb(64,96,128)">&gt;</span>=
 lst <span style=3D"color:rgb(48,128,128)">=3D</span> <span style=3D"color:=
rgb(48,128,128)">.</span><span style=3D"color:rgb(48,128,128)">.</span><spa=
n style=3D"color:rgb(48,128,128)">.</span><span style=3D"color:rgb(64,96,12=
8)">;</span>
  InitializeList<span style=3D"color:rgb(48,128,128)">(</span>lst<span styl=
e=3D"color:rgb(48,128,128)">)</span><span style=3D"color:rgb(64,96,128)">;<=
/span>
  <span style=3D"color:rgb(32,0,128);font-weight:bold">return</span> <span =
style=3D"color:rgb(0,102,238)">std</span><span style=3D"color:rgb(64,96,128=
)">::</span>make_unique<span style=3D"color:rgb(64,96,128)">&lt;</span>Thin=
g<span style=3D"color:rgb(64,96,128)">&gt;</span><span style=3D"color:rgb(4=
8,128,128)">(</span><span style=3D"color:rgb(0,102,238)">std</span><span st=
yle=3D"color:rgb(64,96,128)">::</span><span style=3D"color:rgb(0,48,96)">m<=
wbr>ove</span><span style=3D"color:rgb(48,128,128)">(</span>lst<span style=
=3D"color:rgb(48,128,128)">)</span><span style=3D"color:rgb(48,128,128)">)<=
/span><span style=3D"color:rgb(64,96,128)">;</span>
    <span style=3D"color:rgb(89,89,121)">// Is this copy construction, move=
 construction, or relocation?</span>
<span style=3D"color:rgb(64,96,128)">}</span>

</pre></span></pre></div><div><div>=C2=A0</div></div><div>On the one hand, =
currently, we do not have syntax that the developer could use to ensure mov=
e construction is used,=C2=A0rather than=C2=A0copy construction.</div></div=
></blockquote><div><br>No, but we have an assurance that if `Thing` is move=
able, then it will use move construction. That&#39;s all that is necessary.=
 Remember: movement is an <i>optimization</i> of copying. So if the author =
of `Thing` has decided that his type will not benefit from a move construct=
or, then that&#39;s up to him and the needs of `Thing`. For users of that t=
ype, we assume that we will get the most efficient operation available for =
that type.<br><br>Or to put it another way, you shouldn&#39;t <i>care</i> i=
f it&#39;s really doing a move or a copy. You&#39;re simply giving the obje=
ct the opportunity to make the operation efficient.<br><br>The fundamental =
difference between movement and destructive move is that it is two operatio=
ns in one. It&#39;s a move followed by an ending of the lifetime of the obj=
ect. You can&#39;t ignore or postpone that destruction. It&#39;s not merely=
 an optimized move. It is a fundamentally different type of operation.<br><=
br>Therefore, if you ask for destructive move on a variable, you <i>must ge=
t it</i>. That is, every type must be destructive moveable, even if that op=
eration will simply perform a move/copy followed by a destructor call. The =
only types that are not destructive moveable are those types which are not =
move/copyable at all.<br><br>Move is an optimized copy. Destructive move is=
 an optimization as well. But it&#39;s an optimization of an operation that=
 current does not exist in C++. So your idea is really 2 things:<br><br>1. =
Adding destructive movement as an operation which the user can invoke. This=
 also includes identifying all of the places where destructive movement can=
 be invoked automatically by the compiler.<br><br>2. Adding the ability to =
write specialized destructive move code on a per-object basis. This also ne=
eds to include issues (which your paper didn&#39;t handle) about the <i>ord=
er</i> of the destruction of member elements. C++ has a well-defined order =
that member subobjects are supposed to be destroyed in. A destructor cannot=
 interfere in that order. So neither should a destructive move operation. Y=
our example in your initial proposal showed cases where you change the orde=
r of member subobject destruction.<br><br></div><blockquote class=3D"gmail_=
quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;pa=
dding-left: 1ex;"><div dir=3D"ltr"><div>The developer just has to use synta=
x that allows for move construction, and then count on that a move construc=
tor is available.</div><div><div>=C2=A0</div></div><div>Suppose that we hav=
e relocation, and the compiler has determined to use relocation in the abov=
e example.</div><div><div>=C2=A0</div></div><div>Then, someone modifies=C2=
=A0the above=C2=A0function as follows:</div><div><div>=C2=A0</div></div><di=
v><pre style=3D"background:rgb(246,248,255);color:rgb(0,0,32)"><span style=
=3D"color:rgb(0,102,238)">std</span><span style=3D"color:rgb(64,96,128)">::=
</span><span style=3D"color:rgb(0,48,96)">unique_ptr</span><span style=3D"c=
olor:rgb(64,96,128)">&lt;</span>Thing<span style=3D"color:rgb(64,96,128)">&=
gt;</span> MakeThing<span style=3D"color:rgb(48,128,128)">(</span><span sty=
le=3D"color:rgb(48,128,128)">)</span> <span style=3D"color:rgb(64,96,128)">=
{</span>
  <span style=3D"color:rgb(0,102,238)">std</span><span style=3D"color:rgb(6=
4,96,128)">::</span><span style=3D"color:rgb(0,48,96)">list</span><span sty=
le=3D"color:rgb(64,96,128)">&lt;</span><span style=3D"color:rgb(32,0,128);f=
ont-weight:bold">int</span><span style=3D"color:rgb(64,96,128)">&gt;</span>=
 lst <span style=3D"color:rgb(48,128,128)">=3D</span> <span style=3D"color:=
rgb(48,128,128)">.</span><span style=3D"color:rgb(48,128,128)">.</span><spa=
n style=3D"color:rgb(48,128,128)">.</span><span style=3D"color:rgb(64,96,12=
8)">;</span>
  InitializeList<span style=3D"color:rgb(48,128,128)">(</span>lst<span styl=
e=3D"color:rgb(48,128,128)">)</span><span style=3D"color:rgb(64,96,128)">;<=
/span>
  <span style=3D"color:rgb(32,0,128);font-weight:bold">auto</span> thing <s=
pan style=3D"color:rgb(48,128,128)">=3D</span> <span style=3D"color:rgb(0,1=
02,238)">std</span><span style=3D"color:rgb(64,96,128)">::</span>make_uniqu=
e<span style=3D"color:rgb(64,96,128)">&lt;</span>Thing<span style=3D"color:=
rgb(64,96,128)">&gt;</span><span style=3D"color:rgb(48,128,128)">(</span><s=
pan style=3D"color:rgb(0,102,238)">std</span><span style=3D"color:rgb(64,96=
,128)">::</span><span style=3D"color:rgb(0,48,96)">m<wbr>ove</span><span st=
yle=3D"color:rgb(48,128,128)">(</span>lst<span style=3D"color:rgb(48,128,12=
8)">)</span><span style=3D"color:rgb(48,128,128)">)</span><span style=3D"co=
lor:rgb(64,96,128)">;</span>
  ReuseListForOtherPurpose<span style=3D"color:rgb(48,128,128)">(</span>lst=
<span style=3D"color:rgb(48,128,128)">)</span><span style=3D"color:rgb(64,9=
6,128)">;</span>
  <span style=3D"color:rgb(32,0,128);font-weight:bold">return</span> thing<=
span style=3D"color:rgb(64,96,128)">;</span>
<span style=3D"color:rgb(64,96,128)">}</span>

</pre></div><div><div>=C2=A0</div></div><div><div>Now, this definitely no l=
onger uses relocation,=C2=A0because <i>lst</i> is being=C2=A0used again.</d=
iv><div><br></div><div>Is this a concern? How do we prevent this?</div><div=
><br></div><div>To avoid introducing a keyword, one way could be to add a b=
lessed standard library function, say <i>std::final_reference</i>: </div><d=
iv><br></div><div><pre style=3D"background:rgb(246,248,255);color:rgb(0,0,3=
2)"><span style=3D"color:rgb(0,102,238)">std</span><span style=3D"color:rgb=
(64,96,128)">::</span><span style=3D"color:rgb(0,48,96)">unique_ptr</span><=
span style=3D"color:rgb(64,96,128)">&lt;</span>Thing<span style=3D"color:rg=
b(64,96,128)">&gt;</span> MakeThing<span style=3D"color:rgb(48,128,128)">(<=
/span><span style=3D"color:rgb(48,128,128)">)</span> <span style=3D"color:r=
gb(64,96,128)">{</span>
  <span style=3D"color:rgb(0,102,238)">std</span><span style=3D"color:rgb(6=
4,96,128)">::</span><span style=3D"color:rgb(0,48,96)">list</span><span sty=
le=3D"color:rgb(64,96,128)">&lt;</span><span style=3D"color:rgb(32,0,128);f=
ont-weight:bold">int</span><span style=3D"color:rgb(64,96,128)">&gt;</span>=
 lst <span style=3D"color:rgb(48,128,128)">=3D</span> <span style=3D"color:=
rgb(48,128,128)">.</span><span style=3D"color:rgb(48,128,128)">.</span><spa=
n style=3D"color:rgb(48,128,128)">.</span><span style=3D"color:rgb(64,96,12=
8)">;</span>
  InitializeList<span style=3D"color:rgb(48,128,128)">(</span>lst<span styl=
e=3D"color:rgb(48,128,128)">)</span><span style=3D"color:rgb(64,96,128)">;<=
/span>
  <span style=3D"color:rgb(32,0,128);font-weight:bold">auto</span> thing <s=
pan style=3D"color:rgb(48,128,128)">=3D</span> <span style=3D"color:rgb(0,1=
02,238)">std</span><span style=3D"color:rgb(64,96,128)">::</span>make_uniqu=
e<span style=3D"color:rgb(64,96,128)">&lt;</span>Thing<span style=3D"color:=
rgb(64,96,128)">&gt;</span><span style=3D"color:rgb(48,128,128)">(</span><s=
pan style=3D"color:rgb(0,102,238)">std</span><span style=3D"color:rgb(64,96=
,128)">::</span>f<wbr>inal_reference<span style=3D"color:rgb(48,128,128)">(=
</span>lst<span style=3D"color:rgb(48,128,128)">)</span><span style=3D"colo=
r:rgb(48,128,128)">)</span><span style=3D"color:rgb(64,96,128)">;</span>
  ReuseListForOtherPurpose<span style=3D"color:rgb(48,128,128)">(</span>lst=
<span style=3D"color:rgb(48,128,128)">)</span><span style=3D"color:rgb(64,9=
6,128)">;</span>  <span style=3D"color:rgb(89,89,121)">// Error: use of &qu=
ot;lst&quot; after final_reference</span>
  <span style=3D"color:rgb(32,0,128);font-weight:bold">return</span> thing<=
span style=3D"color:rgb(64,96,128)">;</span>
<span style=3D"color:rgb(64,96,128)">}</span>

</pre></div><div><br></div></div><div><div>This would require a compiler to=
 detect the reuse of &quot;lst&quot; after it&#39;s used in=C2=A0<i>std::fi=
nal_reference</i>, and flag an error when &quot;lst&quot; is reused.</div><=
div><br></div><div>An alternative to a blessed function would be a new keyw=
ord, e.g. &quot;final_reference&quot;.=C2=A0</div></div></div></blockquote>=
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div><br=
></div><div>Thoughts? Ideas?</div></div></div></blockquote><div><br>This is=
 one of the big problems with destructive move as a concept.<br><br>When yo=
u explicitly invoke a destructive move, you are destroying the object. But =
we normally don&#39;t allow you to directly destroy automatic variables. Be=
cause the compiler is going to destroy them later. Permitting the user to d=
estroy automatic variables can get into all kinds of problems.<br><br>What =
if you invoke the destructive move on the variable conditionally? Does the =
compiler need to keep around a hidden boolean variable to know if the autom=
atic variable has been destroyed? What if you invoke it as part of a long e=
xpression, and C++&#39;s undefined order of expression evaluation starts ge=
tting in the way? And so forth.<br><br>Whether it&#39;s done by some standa=
rd library function or a language keyword, these problems persist.<br><br>T=
his is one of the reasons why you need to do more research on this topic. T=
his stuff has been discussed at length, and these issues (among others) hav=
e been brought up before.<br></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/d67f8331-d920-415d-8f71-0af7397dd2c6%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/d67f8331-d920-415d-8f71-0af7397dd2c6=
%40isocpp.org</a>.<br />

------=_Part_1171_706801045.1460311658418--
------=_Part_1170_2059248401.1460311658407--

.
