220 36346 <924751e5-c880-42aa-95ab-99ef1050be2e@isocpp.org> article
Path: news.gmane.org!.POSTED!not-for-mail
From: Nicol Bolas <jmckesson@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Re: Sub-objects and their copy ellision
Date: Mon, 25 Dec 2017 11:15:57 -0800 (PST)
Lines: 435
Approved: news@gmane.org
Message-ID: <924751e5-c880-42aa-95ab-99ef1050be2e@isocpp.org>
References: <caca241d-3498-b79b-fbf3-e57d8b7c3518@technion.ac.il>
 <1c6eff77-d71f-4dd7-8c13-f609460a03f0@isocpp.org> <c14fe13b-a658-e295-40a6-1465638d18db@technion.ac.il>
 <3ec0bd22-b228-4026-bb49-aec5102918c7@isocpp.org>
 <CAKqmYPbdMjxUOp9u+Ercx+eYjvUJvAn+CZe5EDpgGd4vaz47ag@mail.gmail.com>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_16495_1086335912.1514229357820"
X-Trace: blaine.gmane.org 1514229242 1252 195.159.176.226 (25 Dec 2017 19:14:02 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Mon, 25 Dec 2017 19:14:02 +0000 (UTC)
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBCEKFTV6ZUMBB3U4QXJAKGQERICJTSI@isocpp.org Mon Dec 25 20:13:58 2017
Return-path: <std-proposals+bncBCEKFTV6ZUMBB3U4QXJAKGQERICJTSI@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-vk0-f69.google.com ([209.85.213.69])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBCEKFTV6ZUMBB3U4QXJAKGQERICJTSI@isocpp.org>)
	id 1eTYCD-0008LJ-RJ
	for gclcip-std-proposals@m.gmane.org; Mon, 25 Dec 2017 20:13:58 +0100
Original-Received: by mail-vk0-f69.google.com with SMTP id o70sf17537430vke.6
        for <gclcip-std-proposals@m.gmane.org>; Mon, 25 Dec 2017 11:16:00 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=date:from:to:message-id:in-reply-to:references:subject:mime-version
         :x-original-sender:reply-to:precedence:mailing-list:list-id
         :list-post:list-help:list-archive:list-subscribe:list-unsubscribe;
        bh=ZK/Qs7PvMJixjPEcNoHBmCW4v9QnE8zJHIbH89eD2do=;
        b=wHBtshuQQoKIeLarv9YhzEpcCsRzUwrP23r0BdUzeQqRk5VziNAOqCPZF2UjQYWzbe
         pZ7CZcz+b1MIMyQcmaiKyUodHqrLEyGApGXCLXe1c2UeDqMLCb+wpN4tAr608YJKfXGY
         re9hxCh89G8r2QBabagHydQt/mBkUhjgEhoJuPK3+Y3DKiiHQh1/KP/egon1XUKWoWy4
         IgakP0wklusr+0XLsrAs0QsqbsbS+QIFVP7QGvYJ07+Wep23f5PCdeMhiqwoikKeWvyt
         f/YSYMODQWWKj51emeSRGRD91Hwc0HHQZ93EWZ/bWmdKgwv8JTIOgT8v7nAXJHkbA+u5
         5jXQ==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20161025;
        h=date:from:to:message-id:in-reply-to:references:subject:mime-version
         :x-original-sender:reply-to:precedence:mailing-list:list-id
         :list-post:list-help:list-archive:list-subscribe:list-unsubscribe;
        bh=ZK/Qs7PvMJixjPEcNoHBmCW4v9QnE8zJHIbH89eD2do=;
        b=fNexAcZHJObOIZZPOj3tjE1Q/cGVUyabFrAp/dcjSHeq7LNjVKcbkIxqny8veeZCZv
         o5SGVnH6HMOQ32Z7TYloeVUwGiMbInTjYhJN6ysiWUAUMRspksTQeOgpNK6ImufBLlHp
         MY0cdxxvH9lcr5ZC3gXxLBkTg31ABQa6jFoIym/NV8qTO+czKsh1CVz7K1EsuU7oyYrW
         DLJstcOi0lKg7JePlzwyUFXsRyeRzVfUnaSG6Cyu9bkfHoj5xszhtoZkheXbMZl78MPA
         eLN7+HiScZt8PiMBbgHxy32mB/UH1qChoByxuhR8epSN/Necb3QuyJkyzMilJYyQNlfO
         eYZA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20161025;
        h=x-gm-message-state:date:from:to: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=ZK/Qs7PvMJixjPEcNoHBmCW4v9QnE8zJHIbH89eD2do=;
        b=G3TJvGTOPZjDFMyt2qsqKINeSPiIqY6flyVHIqFHvINGMlin56/cUFKIDf1WMMjfH0
         Ts4DYManBvCjEXyOyloDNyN+FAs4fVEMbHAmKmmAoU0i3eMWEl8TcB/5P+SVIU67V55w
         F48955R0WdrgJnKsYWlbdFzg2ZVip4w4lpeb5WnFaXypJUB+nqt07l1755rfdnN1zRir
         L2gpP22z2kmeizSM5K+4tWkBAP5LQf4ArD3nl6wI8hddQ3/IA1TpaJ08tw4FU8PtcXMm
         XNoBwMFvxMn1xv3IHgExm3R1hySf2CgwWP+Eb57O+MNyaUi7ZUVzi1+mLIq0bOhv0mN3
         bleA==
X-Gm-Message-State: AKGB3mLsl3Ew/mxqTLbAmccxy3cr+MFGpM2sX5S0mf5uGUO3L8rLrwCV
	oMv1iS+zTm5CgnhPiwiRteVCAg==
X-Google-Smtp-Source: ACJfBotYpSLIo9ngbnS0J3+oBA+2T/qgxC/IxpI9sT5UzWBgMUsAzC7CQwwZZ6i9DdTzdjmXwlo6Sw==
X-Received: by 10.176.70.93 with SMTP id z29mr10934819uab.94.1514229360198;
        Mon, 25 Dec 2017 11:16:00 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.176.84.150 with SMTP id p22ls1956276uaa.5.gmail; Mon, 25 Dec
 2017 11:15:58 -0800 (PST)
X-Received: by 10.31.2.144 with SMTP id 138mr2140766vkc.5.1514229358443;
        Mon, 25 Dec 2017 11:15:58 -0800 (PST)
In-Reply-To: <CAKqmYPbdMjxUOp9u+Ercx+eYjvUJvAn+CZe5EDpgGd4vaz47ag@mail.gmail.com>
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:36346
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/36346>

------=_Part_16495_1086335912.1514229357820
Content-Type: multipart/alternative; 
	boundary="----=_Part_16496_647231060.1514229357821"

------=_Part_16496_647231060.1514229357821
Content-Type: text/plain; charset="UTF-8"

On Monday, December 25, 2017 at 1:12:19 PM UTC-5, Antony Polukhin wrote:
>
> On Dec 20, 2017 04:06, "Nicol Bolas" <jmck...@gmail.com <javascript:>> 
> wrote:
> <...>
>
> Just within this thread, we have identified a number of limitations on 
> what you can do with such objects. Let's not go further than merely what 
> you've already agree to: destruction of subobjects and layout. That is, 
> this optimization is not possible if any of the following is true:
>
> 1) The containing type has a non-defaulted destructor.
> 2) The containing object is not passed to another function by pointer or 
> reference, since that requires the object's layout to be consistent with 
> what the standard says.
> 3) The user of the containing object does not do anything layout-specific 
> itself.
>
> Note that this is almost certainly* not* a complete list. It's merely the 
> ones talked about thus far; there are almost certainly others.
>
>
> Since late November paper concentrates on cases when the callee is inlined.
>

OK, so now we've added a fourth requirement: the function must be 
inlinable. Not declared `inline` or something that can be checked by actual 
C++ syntax, but some nebulous "inlineable".

Why is this circumstance important enough to be *worth* all of this hassle?
 

> In that case there's no need to mess with the object layout. But please, 
> wait for a moment and read further. I know that this point rises even more 
> questions.
>
>
>
>
> Item #2 is particularly important. Why? Because that rules out calling* 
> any member functions*, since all non-static member functions take the 
> object by pointer. And that requires the object's layout to be consistent 
> with its definition.
>
> Notice that "Motivating example #2" doesn't qualify for this, since we 
> call a function on the object. That requires it to have a certain layout.
>
> So, how much real code actually qualifies for such elision?
>
> Because here's the thing the person behind that proposal just doesn't get. 
> His proposal* doesn't work*. It does not solve the problem. Why?
>
> Because compilers can't do it in so many of these cases. RVO was very 
> reliable; when compilers offered it, it worked for any case of returning a 
> prvalue. NRVO is pretty reliable; declare the variable at the top of the 
> function, return it whenever, and you're almost guaranteed to get the 
> optimization.
>
>
> That's true. But let me put it other way around.
>
> Compilers could do devirtualization. Does this optimization reliable? No, 
> it is very dependent on the compiler abilities and flags. Does the C++ 
> Standard forbids that optimization? No, because it's an optimization and 
> users may benefit from it.
>
> Just treat optimization from the "subobject copy elision" paper as some 
> random optimization: not something you could rely on, but something that 
> may help if compiler is clever enough.
>

Then why take the time to change the standard to allow it?

What are the guidelines for getting this proposal's optimizations? What 
> circumstances stop it, and what can be done to avoid them?
>
> Because here's the thing: if I do this:
>
> string foo()
> {
>   string str;
>   str = ...;
>   return str;
> }
>
> If I do that, and I* don't* get elision, it's still fine. Why? Because I 
> still get automatic move support. `str` in the return statement is a 
> reference to an automatic variable in the function's scope, so it is moved 
> from. I may not have gotten the best answer, but I got a good enough one.
>
> In this case:
>
> string foo()
> {
>   pair<string, string> pr = ...;
>   return pr.second;
> }
>
> What happens if this doesn't get elided? Well, you get a copy. The only 
> way to get a move is to ask for it: `return std::move(pr.second)`.
>
>
> So the proposal actually* encourages bad code*, on the assumption that 
> the compiler will swoop in and save you.
>
>
> You've got that impression from the assumption that the optimization is 
> something you could rely on, which is not true.
>

But we do rely on it.

When people write this code:

T func()
{
  T t;
  t.something();
  do_other_thing(t);
  return t;
};

It is written with the expectation that, on most compilers, this will not 
perform unnecessary copies/moves. Pretty much every compiler still in use 
gets this code right.

It doesn't matter if `func` is "inlineable" from the site of where you call 
`func`. It doesn't matter how big `T` is or whether its trivial or not (OK, 
some ABIs make trivial types under a certain size go into registers, but 
that's *better* than copy elision...). This being optimized depends on 
exactly two factors: how you write `func`, and how your compiler compiles 
`func`. If you write `func` in a certain way, you have reasonable assurance 
that compilers worth using will optimize it.

There is no such guideline for the cases you describe. They're all based on 
various nebulous properties and random code transformation and the like.

But the example with std::move that disables the copy elision is a good 
> catch. I've been thinking on that problem a lot a few weeks ago and 
> suddenly came up with a more generic solution: 
> http://apolukhin.github.io/papers/ultimate_copy_elision.html
>
> I'd be grateful if you and other volunteers could take a look at it. It 
> addresses most of the above comments.
>

It addresses them poorly.

> Concern: Eliding copy/move constructors could break user code
> Resp: Yes, but only if the following constraint for copy constructor is 
not satisfied: "After the definition T u = v;, u is equal to v".

What does "equal to" mean in this context? It is perfectly legitimate for 
every instance of a `T` to have a unique identifying integer. The 
comparison for `T` wouldn't compare this integer, but it certainly* could* 
use the integer in other behavior (ie: strong vs. weak equality in 
`operator<=>`).

Equally importantly, you're missing the issue of extracting a subobject 
from an object without actually *extracting it*. I can no longer assume 
that the object I construct as a subobject is in any way part of myself, 
nor can it assume that any sibling subobjects will always be around. And 
there's no way to declare that `T` is a type for which those subobjects 
still being around matters.

> Concern: We want an emergency hatch to disable copy elision for 
particular places.
> Resp: Usual practice to disable optimizations for a variable is to make 
it volatile. This feature must be kept.

But `volatile` carries with it a* ton* of other baggage.

> Concern: The problem is not that big. Compilers could inline the 
constructors and destructors and optimize the resulting code
> Resp: Unfortunately it is much harder to analyze the resulting code and 
compilers fail in too many cases.

But you've presented no evidence that what you propose will make* any* of 
those "too many cases" more optimal. There are no guarantees that the 
compiler will optimize any of those.

Also, you never actually dealt with the main part of this argument: that "the 
problem is not that big". Because it isn't that big.

-- 
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/924751e5-c880-42aa-95ab-99ef1050be2e%40isocpp.org.

------=_Part_16496_647231060.1514229357821
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Monday, December 25, 2017 at 1:12:19 PM UTC-5, Antony P=
olukhin wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"=
><div dir=3D"auto"><div><div><div class=3D"gmail_quote">On Dec 20, 2017 04:=
06, &quot;Nicol Bolas&quot; &lt;<a onmousedown=3D"this.href=3D&#39;javascri=
pt:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return =
true;" href=3D"javascript:" target=3D"_blank" rel=3D"nofollow" gdf-obfuscat=
ed-mailto=3D"HTMDmcZUCAAJ">jmck...@gmail.com</a>&gt; wrote:</div><div class=
=3D"gmail_quote">&lt;...&gt;<br><blockquote style=3D"margin:0px 0px 0px 0.8=
ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr=
"><div></div><div>Just within this thread, we have identified a number of l=
imitations on what you can do with such objects. Let&#39;s not go further t=
han merely what you&#39;ve already agree to: destruction of subobjects and =
layout. That is, this optimization is not possible if any of the following =
is true:</div><div><br></div><div>1) The containing type has a non-defaulte=
d destructor.</div><div>2) The containing object is not passed to another f=
unction by pointer or reference, since that requires the object&#39;s layou=
t to be consistent with what the standard says.</div><div>3) The user of th=
e containing object does not do anything layout-specific itself.</div><div>=
<br></div><div>Note that this is almost certainly<i> not</i> a complete lis=
t. It&#39;s merely the ones talked about thus far; there are almost certain=
ly others.</div></div></blockquote></div></div></div><div dir=3D"auto"><br>=
</div><div dir=3D"auto">Since late November paper concentrates on cases whe=
n the callee is inlined.</div></div></div></blockquote><div><br></div><div>=
OK, so now we&#39;ve added a fourth requirement: the function must be inlin=
able. Not declared `inline` or something that can be checked by actual C++ =
syntax, but some nebulous &quot;inlineable&quot;.</div><div><br></div><div>=
Why is this circumstance important enough to be <i>worth</i> all of this ha=
ssle?</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><d=
iv dir=3D"ltr"><div dir=3D"auto"><div dir=3D"auto">In that case there&#39;s=
 no need to mess with the object layout. But please, wait for a moment and =
read further. I know that this point rises even more questions.</div><div d=
ir=3D"auto"><div><div class=3D"gmail_quote"><blockquote style=3D"margin:0px=
 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><di=
v dir=3D"ltr"><div><i></i></div></div></blockquote></div></div></div><div d=
ir=3D"auto"><br></div><div dir=3D"auto"><br></div><div dir=3D"auto"><div><d=
iv class=3D"gmail_quote"><blockquote style=3D"margin:0px 0px 0px 0.8ex;bord=
er-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>=
<i><br></i></div><div>Item #2 is particularly important. Why? Because that =
rules out calling<i> any member functions</i>, since all non-static member =
functions take the object by pointer. And that requires the object&#39;s la=
yout to be consistent with its definition.</div><div><br></div><div>Notice =
that &quot;<span style=3D"display:inline;float:none;background-color:transp=
arent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quo=
t;,sans-serif;font-size:13px;font-style:normal;font-variant:normal;font-wei=
ght:400;letter-spacing:normal;text-align:left;text-decoration:none;text-ind=
ent:0px;text-transform:none;white-space:normal;word-spacing:0px">Motivating=
 example #2&quot; doesn&#39;t qualify for this, since we call a function on=
 the object. That requires it to have a certain layout.</span></div><div><s=
pan style=3D"display:inline;float:none;background-color:transparent;color:r=
gb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif=
;font-size:13px;font-style:normal;font-variant:normal;font-weight:400;lette=
r-spacing:normal;text-align:left;text-decoration:none;text-indent:0px;text-=
transform:none;white-space:normal;word-spacing:0px"><br></span></div><div>S=
o, how much real code actually qualifies for such elision?</div><div><br></=
div><div>Because here&#39;s the thing the person behind that proposal just =
doesn&#39;t get. His proposal<i> doesn&#39;t work</i>. It does not solve th=
e problem. Why?</div><div><br></div><div>Because compilers can&#39;t do it =
in so many of these cases. RVO was very reliable; when compilers offered it=
, it worked for any case of returning a prvalue. NRVO is pretty reliable; d=
eclare the variable at the top of the function, return it whenever, and you=
&#39;re almost guaranteed to get the optimization.</div></div></blockquote>=
</div></div></div><div dir=3D"auto"><br></div><div dir=3D"auto">That&#39;s =
true. But let me put it other way around.</div><div dir=3D"auto"><br></div>=
<div dir=3D"auto">Compilers could do devirtualization. Does this optimizati=
on reliable? No, it is very dependent on the compiler abilities and flags. =
Does the C++ Standard forbids that optimization? No, because it&#39;s an op=
timization and users may benefit from it.</div><div dir=3D"auto"><br></div>=
<div dir=3D"auto">Just treat optimization from the &quot;subobject copy eli=
sion&quot; paper as some random optimization: not something you could rely =
on, but something that may help if compiler is clever enough.</div></div></=
div></blockquote><div><br></div><div>Then why take the time to change the s=
tandard to allow it?</div><div><br></div><blockquote class=3D"gmail_quote" =
style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-l=
eft: 1ex;"><div dir=3D"ltr"><div dir=3D"auto"><div dir=3D"auto"><div><div c=
lass=3D"gmail_quote"><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-l=
eft:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>What=
 are the guidelines for getting this proposal&#39;s optimizations? What cir=
cumstances stop it, and what can be done to avoid them?</div><div><br></div=
><div>Because here&#39;s the thing: if I do this:</div><div><br></div><div =
style=3D"border-color:rgb(187,187,187);border-style:solid;border-width:1px;=
background-color:rgb(250,250,250)"><code><div><span style=3D"color:rgb(0,0,=
136)">string</span><span style=3D"color:rgb(0,0,0)"> foo</span><span style=
=3D"color:rgb(102,102,0)">()</span><span style=3D"color:rgb(0,0,0)"><br></s=
pan><span style=3D"color:rgb(102,102,0)">{</span><span style=3D"color:rgb(0=
,0,0)"><br>=C2=A0 </span><span style=3D"color:rgb(0,0,136)">string</span><s=
pan style=3D"color:rgb(0,0,0)"> str</span><span style=3D"color:rgb(102,102,=
0)">;</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 str </span><span st=
yle=3D"color:rgb(102,102,0)">=3D</span><span style=3D"color:rgb(0,0,0)"> </=
span><span style=3D"color:rgb(102,102,0)">...;</span><span style=3D"color:r=
gb(0,0,0)"><br>=C2=A0 </span><span style=3D"color:rgb(0,0,136)">return</spa=
n><span style=3D"color:rgb(0,0,0)"> str</span><span style=3D"color:rgb(102,=
102,0)">;</span><span style=3D"color:rgb(0,0,0)"><br></span><span style=3D"=
color:rgb(102,102,0)">}</span></div></code></div><div><br></div><div>If I d=
o that, and I<i> don&#39;t</i> get elision, it&#39;s still fine. Why? Becau=
se I still get automatic move support. `str` in the return statement is a r=
eference to an automatic variable in the function&#39;s scope, so it is mov=
ed from. I may not have gotten the best answer, but I got a good enough one=
..</div><div><br></div><div>In this case:</div><div><br></div><div style=3D"=
border-color:rgb(187,187,187);border-style:solid;border-width:1px;backgroun=
d-color:rgb(250,250,250)"><code><div><span style=3D"color:rgb(0,0,136)">str=
ing</span><span style=3D"color:rgb(0,0,0)"> foo</span><span style=3D"color:=
rgb(102,102,0)">()</span><span style=3D"color:rgb(0,0,0)"><br></span><span =
style=3D"color:rgb(102,102,0)">{</span><span style=3D"color:rgb(0,0,0)"><br=
>=C2=A0 pair</span><span style=3D"color:rgb(102,102,0)">&lt;</span><span st=
yle=3D"color:rgb(0,0,136)">string</span><span style=3D"color:rgb(102,102,0)=
">,</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb=
(0,0,136)">string</span><span style=3D"color:rgb(102,102,0)">&gt;</span><sp=
an style=3D"color:rgb(0,0,0)"> pr </span><span style=3D"color:rgb(102,102,0=
)">=3D</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:=
rgb(102,102,0)">...;</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 </sp=
an><span style=3D"color:rgb(0,0,136)">return</span><span style=3D"color:rgb=
(0,0,0)"> pr</span><span style=3D"color:rgb(102,102,0)">.</span><span style=
=3D"color:rgb(0,0,0)">second</span><span style=3D"color:rgb(102,102,0)">;</=
span><span style=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:rgb(1=
02,102,0)">}</span></div></code></div><div><br></div><div>What happens if t=
his doesn&#39;t get elided? Well, you get a copy. The only way to get a mov=
e is to ask for it: `return std::move(pr.second)`.</div></div></blockquote>=
</div></div></div><div dir=3D"auto"><div><div class=3D"gmail_quote"><blockq=
uote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,20=
4);padding-left:1ex"><div dir=3D"ltr"><div><br></div><div>So the proposal a=
ctually<i> encourages bad code</i>, on the assumption that the compiler wil=
l swoop in and save you.</div></div></blockquote><div dir=3D"ltr"><div><br>=
</div><div>You&#39;ve got that impression from the assumption that the opti=
mization is something you could rely on, which is not true.<br></div></div>=
</div></div></div></div></div></blockquote><div><br></div><div>But we do re=
ly on it.</div><div><br></div><div>When people write this code:</div><div><=
br></div><div class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187=
, 187); word-wrap: break-word; background-color: rgb(250, 250, 250);"><code=
 class=3D"prettyprint"><div class=3D"subprettyprint"><span class=3D"styled-=
by-prettify" style=3D"color: #000;">T func</span><span class=3D"styled-by-p=
rettify" style=3D"color: #660;">()</span><span class=3D"styled-by-prettify"=
 style=3D"color: #000;"><br></span><span class=3D"styled-by-prettify" style=
=3D"color: #660;">{</span><span class=3D"styled-by-prettify" style=3D"color=
: #000;"><br>=C2=A0 T t</span><span class=3D"styled-by-prettify" style=3D"c=
olor: #660;">;</span><span class=3D"styled-by-prettify" style=3D"color: #00=
0;"><br>=C2=A0 t</span><span class=3D"styled-by-prettify" style=3D"color: #=
660;">.</span><span class=3D"styled-by-prettify" style=3D"color: #000;">som=
ething</span><span class=3D"styled-by-prettify" style=3D"color: #660;">();<=
/span><span class=3D"styled-by-prettify" style=3D"color: #000;"><br>=C2=A0 =
do_other_thing</span><span class=3D"styled-by-prettify" style=3D"color: #66=
0;">(</span><span class=3D"styled-by-prettify" style=3D"color: #000;">t</sp=
an><span class=3D"styled-by-prettify" style=3D"color: #660;">);</span><span=
 class=3D"styled-by-prettify" style=3D"color: #000;"><br>=C2=A0 </span><spa=
n class=3D"styled-by-prettify" style=3D"color: #008;">return</span><span cl=
ass=3D"styled-by-prettify" style=3D"color: #000;"> t</span><span class=3D"s=
tyled-by-prettify" style=3D"color: #660;">;</span><span class=3D"styled-by-=
prettify" style=3D"color: #000;"><br></span><span class=3D"styled-by-pretti=
fy" style=3D"color: #660;">};</span></div></code></div><div><br></div><div>=
It is written with the expectation that, on most compilers, this will not p=
erform unnecessary copies/moves. Pretty much every compiler still in use ge=
ts this code right.</div><div><br></div><div>It doesn&#39;t matter if `func=
` is &quot;inlineable&quot; from the site of where you call `func`. It does=
n&#39;t matter how big `T` is or whether its trivial or not (OK, some ABIs =
make trivial types under a certain size go into registers, but that&#39;s <=
i>better</i> than copy elision...). This being optimized depends on exactly=
 two factors: how you write `func`, and how your compiler compiles `func`. =
If you write `func` in a certain way, you have reasonable assurance that co=
mpilers worth using will optimize it.</div><div><br></div><div>There is no =
such guideline for the cases you describe. They&#39;re all based on various=
 nebulous properties and random code transformation and the like.</div><div=
><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"ltr"><d=
iv dir=3D"auto"><div dir=3D"auto"><div><div class=3D"gmail_quote"><div dir=
=3D"ltr"><div></div></div><div dir=3D"ltr">But the example with std::move t=
hat disables the copy elision is a good catch. I&#39;ve been thinking on th=
at problem a lot a few weeks ago and suddenly came up with a more generic s=
olution: <a onmousedown=3D"this.href=3D&#39;http://www.google.com/url?q\x3d=
http%3A%2F%2Fapolukhin.github.io%2Fpapers%2Fultimate_copy_elision.html\x26s=
a\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGKctCTQTa2Lt6fYMOA-sqoZHG2fQ&#39;;retur=
n true;" onclick=3D"this.href=3D&#39;http://www.google.com/url?q\x3dhttp%3A=
%2F%2Fapolukhin.github.io%2Fpapers%2Fultimate_copy_elision.html\x26sa\x3dD\=
x26sntz\x3d1\x26usg\x3dAFQjCNGKctCTQTa2Lt6fYMOA-sqoZHG2fQ&#39;;return true;=
" href=3D"http://apolukhin.github.io/papers/ultimate_copy_elision.html" tar=
get=3D"_blank" rel=3D"nofollow">http://apolukhin.github.io/<wbr>papers/ulti=
mate_copy_elision.<wbr>html</a></div><div><br></div><div>I&#39;d be gratefu=
l if you and other volunteers could take a look at it. It addresses most of=
 the above comments.<br></div></div></div></div></div></div></blockquote><d=
iv><br></div><div>It addresses them poorly.</div><div><br></div><div>&gt; C=
oncern: Eliding copy/move constructors could break user code<br>&gt; Resp: =
Yes, but only if the following constraint for copy constructor is not satis=
fied: &quot;After the definition T u =3D v;, u is equal to v&quot;.</div><d=
iv><br></div><div>What does &quot;equal to&quot; mean in this context? It i=
s perfectly legitimate for every instance of a `T` to have a unique identif=
ying integer. The comparison for `T` wouldn&#39;t compare this integer, but=
 it certainly<i> could</i> use the integer in other behavior (ie: strong vs=
.. weak equality in `operator&lt;=3D&gt;`).</div><div><br></div><div>Equally=
 importantly, you&#39;re missing the issue of extracting a subobject from a=
n object without actually <i>extracting it</i>. I can no longer assume that=
 the object I construct as a subobject is in any way part of myself, nor ca=
n it assume that any sibling subobjects will always be around. And there&#3=
9;s no way to declare that `T` is a type for which those subobjects still b=
eing around matters.</div><div><i><br></i></div><div>&gt;=C2=A0Concern: We =
want an emergency hatch to disable copy elision for particular places.<br>&=
gt; Resp: Usual practice to disable optimizations for a variable is to make=
 it volatile. This feature must be kept.</div><div><br></div><div>But `vola=
tile` carries with it a<i> ton</i> of other baggage.</div><div><br></div><d=
iv>&gt;=C2=A0Concern: The problem is not that big. Compilers could inline t=
he constructors and destructors and optimize the resulting code<br>&gt; Res=
p: Unfortunately it is much harder to analyze the resulting code and compil=
ers fail in too many cases.</div><div><br></div><div>But you&#39;ve present=
ed no evidence that what you propose will make<i> any</i> of those &quot;to=
o many cases&quot; more optimal. There are no guarantees that the compiler =
will optimize any of those.</div><div><br></div><div>Also, you never actual=
ly dealt with the main part of this argument: that &quot;<span style=3D"dis=
play: inline !important; float: none; background-color: transparent; color:=
 rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans=
-serif; font-size: 13px; font-style: normal; font-variant: normal; font-wei=
ght: 400; letter-spacing: normal; orphans: 2; text-align: left; text-decora=
tion: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-wid=
th: 0px; white-space: normal; word-spacing: 0px;">the </span>problem is not=
 that big&quot;. Because it isn&#39;t that big.</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/924751e5-c880-42aa-95ab-99ef1050be2e%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/924751e5-c880-42aa-95ab-99ef1050be2e=
%40isocpp.org</a>.<br />

------=_Part_16496_647231060.1514229357821--

------=_Part_16495_1086335912.1514229357820--

.
