220 28026 <CAE7XuEWB6sT8E2bFXC1D291vKna2CLh8Z4+jp3M1=s5=t4M2fw@mail.gmail.com> article
Path: news.gmane.org!.POSTED!not-for-mail
From: Nicolas Capens <nicolas.capens@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Specifier to cause the destructor to be called at
 last use instead of end of scope
Date: Mon, 29 Aug 2016 21:21:12 +0000
Lines: 343
Approved: news@gmane.org
Message-ID: <CAE7XuEWB6sT8E2bFXC1D291vKna2CLh8Z4+jp3M1=s5=t4M2fw@mail.gmail.com>
References: <ec2e95cc-3ef0-435b-aaf9-13e982c4583e@isocpp.org>
 <CAA7YVg3dJT3LY_L5Eg=ZNgfqqyOcX9P=JVv_pXTEx6xxsoGOdg@mail.gmail.com>
 <CAE7XuEWr7eyyjmqURnMwQf1pvyvHeMATM1MDjRY=25WuGy5Z=w@mail.gmail.com> <16f4f27a-daf4-4eff-8408-73aadc99e0c5@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/alternative; boundary=94eb2c0584542c4d38053b3c7208
X-Trace: blaine.gmane.org 1472505694 12530 195.159.176.226 (29 Aug 2016 21:21:34 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Mon, 29 Aug 2016 21:21:34 +0000 (UTC)
To: Nicol Bolas <jmckesson@gmail.com>, 
	"ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBC6MN3XGLYINPTUSXYCRUBHADZNOM@isocpp.org Mon Aug 29 23:21:29 2016
Return-path: <std-proposals+bncBC6MN3XGLYINPTUSXYCRUBHADZNOM@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-pa0-f70.google.com ([209.85.220.70])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBC6MN3XGLYINPTUSXYCRUBHADZNOM@isocpp.org>)
	id 1beTzj-0002Xt-Fx
	for gclcip-std-proposals@m.gmane.org; Mon, 29 Aug 2016 23:21:27 +0200
Original-Received: by mail-pa0-f70.google.com with SMTP id ag5sf355191pad.2
        for <gclcip-std-proposals@m.gmane.org>; Mon, 29 Aug 2016 14:21:28 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=mime-version:references:in-reply-to:from:date:message-id:subject:to
         :x-original-sender:x-original-authentication-results:reply-to
         :precedence:mailing-list:list-id:x-spam-checked-in-group:list-post
         :list-help:list-archive:list-subscribe:list-unsubscribe;
        bh=F228F5hlShfBa08ko1w1Xcb+TIzqfrqmc5Ys9v0MZuo=;
        b=s6HNqkZIlNok/Nr24TVxu3FatiF3NTUlirb/z2d7+ujo6B1qHWokYFDZKvp0nz05w3
         3u1XVhFKhuOpOLunOmyvEM1Nwv73wqsJKjbG5cGv53lPXuvXOt+fXssbIdvXgBl9PriV
         x18ED0rYF8urDsV8ZRO9w3DfwFqt1qVmyNM0xLVsGleWa86hwV5E/ofBasuQbxF2wd82
         S0KDXjIxC2L45mRYYlVzISZfYpm4L+OWuCPgx94WayNVNQf0K1DWOd2qFdor9z+cdyAW
         mI+GffOS4KGS8faafeSWFzC8bqlsheIp5A0mALfYJYKRyci06bVcBW/scfWCFAklIJ1C
         GVWA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:mime-version:references:in-reply-to:from:date
         :message-id:subject:to:x-original-sender
         :x-original-authentication-results:reply-to:precedence:mailing-list
         :list-id:x-spam-checked-in-group:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=F228F5hlShfBa08ko1w1Xcb+TIzqfrqmc5Ys9v0MZuo=;
        b=HkZ7YC51V715qq4YNqM6u3ISFbcWxrP2f2/us5fSnhpWCUQu/QHuOPsp7YzjRE7MpP
         XTBKKAPkX8myQsCo6YyD8phAzOroDth2P3p37HyTIKye03dF2jy2yy7OKyg88ZDeI4uv
         PG5Gob9JPP15vJawEY3+AExbNNeNi5d4Z2dBFC5HLK6lUPusXZ08a58Z3+R+EuPQmn4T
         qrCDlWqCx7mEOy+PdO7gegQ6n7S6KeKk3khHzAPhiSVXFIUAokti1d1KMwXT3TNxIVFB
         X1faZvaOoL9jf+2ysqblUSCDhSMB5/9h//06EmKLmZsvIb5ha6isrTsVMv3eOigieVEn
         weiQ==
X-Gm-Message-State: AE9vXwOrIrzMU5B2xxQyOB6Blz96VGhuP5FQlHSPbLBxk1rjr0mKyo3UyzW6ImaRvAdZfA==
X-Received: by 10.98.20.196 with SMTP id 187mr124130pfu.0.1472505688067;
        Mon, 29 Aug 2016 14:21:28 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.157.24.71 with SMTP id t7ls9061760ott.5.gmail; Mon, 29 Aug
 2016 14:21:27 -0700 (PDT)
X-Received: by 10.55.106.2 with SMTP id f2mr166354qkc.124.1472505687030;
        Mon, 29 Aug 2016 14:21:27 -0700 (PDT)
Original-Received: from mail-qk0-x233.google.com (mail-qk0-x233.google.com. [2607:f8b0:400d:c09::233])
        by mx.google.com with ESMTPS id 13si22990050qkq.183.2016.08.29.14.21.26
        for <std-proposals@isocpp.org>
        (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
        Mon, 29 Aug 2016 14:21:26 -0700 (PDT)
Received-SPF: pass (google.com: domain of nicolas.capens@gmail.com designates 2607:f8b0:400d:c09::233 as permitted sender) client-ip=2607:f8b0:400d:c09::233;
Original-Received: by mail-qk0-x233.google.com with SMTP id v123so252758qkh.2
        for <std-proposals@isocpp.org>; Mon, 29 Aug 2016 14:21:26 -0700 (PDT)
X-Received: by 10.55.104.135 with SMTP id d129mr154452qkc.126.1472505683134;
 Mon, 29 Aug 2016 14:21:23 -0700 (PDT)
In-Reply-To: <16f4f27a-daf4-4eff-8408-73aadc99e0c5@isocpp.org>
X-Original-Sender: Nicolas.Capens@gmail.com
X-Original-Authentication-Results: mx.google.com;       dkim=pass
 header.i=@gmail.com;       spf=pass (google.com: domain of
 nicolas.capens@gmail.com designates 2607:f8b0:400d:c09::233 as permitted
 sender) smtp.mailfrom=nicolas.capens@gmail.com;       dmarc=pass (p=NONE
 dis=NONE) header.from=gmail.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <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:28026
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/28026>

--94eb2c0584542c4d38053b3c7208
Content-Type: text/plain; charset=UTF-8

On Sat, Aug 27, 2016 at 11:10 AM Nicol Bolas <jmckesson@gmail.com> wrote:

> On Thursday, August 25, 2016 at 5:24:39 PM UTC-4, Nicolas Capens wrote:
>>
>> Thanks all for the initial feedback! It's clear to me now that I haven't
>> defined "last use" very well, and giving it an accurate definition based on
>> my limited knowledge of compiler lingo is going to be tricky.
>>
>> So let me take a step back and describe what real-world issues I'm trying
>> to solve. The first example is one where I'd like the heap memory managed
>> by an object to get freed at the same point where a scalar variable's
>> register would be made available for a different variable:
>>
>
> I don't think anyone misunderstands what your *intended use cases* are.
> But the fact is that things do not get used the way they are intended at
> all times.
>
> Consider a basic bit of template programming:
>
> T t = ...
> auto tpl = forward_as_tuple(t);
> //do something with tpl.
>
> This code, today, works for any type `T` which can be constructed with
> whatever ... was. Your feature would now make this code *suspect*. It
> would *only work* for `T`s that do not use "eager" destruction. So if
> someone wanted to instantiate this template with your `Matrix` type, this
> code breaks.
>

There are already many situations in which seemingly well understood code
can behave differently than expected. Copy elision, exceptions,
platform-specific typedefs, operator overloading, and virtual functions are
all known to catch people by surprise. It's an inherent property of C++
that many different things can happen behind our backs, which can also be
incredibly powerful. So I think eager destruction might require tossing
some old assumptions out of the window, but it will enable some valuable
new optimizations.

Normal amounts of compiler analysis cannot fix that. After all, the
> compiler doesn't (necessarily) know what's going on in `forward_as_tuple`.
> All the compiler sees is that you're passing a reference in, and you're
> getting at tuple<T&> out. How could the compiler know that `tpl` contains a
> reference to `t`? It can't; not without doing *serious* usage analysis.
>
> And that's for a *simple* case; `forward_as_tuple` is a template
> function, so the compiler has its implementation. It could have been a
> non-template function that wasn't inlined. At which point, it requires
> whole program analysis to know *for certain* that the return value
> contains a reference to a function parameter.
>

I'm not entirely convinced yet that this is unreasonable to be expected
from a modern compiler. Destruction at the end of the scope,
interprocedural register allocation, and garbage collection all have
existed for decades. Isn't it time to add a new option which might require
some static analysis? If not now, can we have it the next century? Either
way I feel like we're stuck while technically we're already able to do
better. We just have to be willing to make the necessary changes to the
standard, and figure out the right balance between determinism, ease of
use, conservatism, etc.

By the way, one other potential way this could be solved is to not allow
storing referenced to classes with eager destruction. That is, they can be
function arguments, but they can't be member variables or global variables.
The above code would then simply not compile and you'd get a clear error
message about it.


> Remember: this is the confounding problem with temporary lifetime
> extension, when passing temporaries through functions.
>
> Who's fault is this failure? Is it the fault of the person who wrote this
> template code without knowing that such a feature was going to be
> introduced? No, of course not. It has to be the fault of the person who
> passed `Matrix` to this template. But how could they know that `Matrix`'s
> eager destructor would cause the template to break?
>
> Thus, the blame must fall on the feature itself.
>
> Your post talks about the utility of this feature with "scalar types". But
> what you're really talking about is how you *use* the type. The type is
> safe so long as you treat it as a pure value: you never get a
> pointer/reference to it or of its contents. But note where this distinction
> is made. It's not made in the type's declaration (you can get references to
> `int`, after all). It's made *at the point of use*.
>

Taking reference to int is handled by liveness analysis by treating it as
an alias. And when it disappears into an unknown function it can fall back
to keeping the variable live until the end of its scope. But in many cases
it can still optimize register usage, and a crucial part of that is knowing
that there are no noticeable side effects. That's a property of its type.
Likewise I think that for cases where an object is self-contained and we
don't care when the side effects of its destruction happen, that too should
be a property of the type.

Note that I'm not married to this idea. I'm just trying to make sure you
can see things my way as well before we discuss the pros and cons of the
alternatives.


> The problem, as Matt has said, is that your feature works at the *type*
> level. To make this feature work, it has to happen at the *usage* level.
> The person declaring that variable *must explicitly state* that they will
> use the type as a pure value. That they won't get pointers/references to
> itself or its contents.
>
> The right way to handle this is to make it a function of the object's
> declaration:
>
> <some_syntax> TypeName varName;
>

If this can be part of a typedef (like const), then that seems reasonable
to me. Note that I really wouldn't want to annotate the use of a Reactor
<https://swiftshader.googlesource.com/SwiftShader/+/HEAD/docs/Reactor.md>
type at each variable declaration.

I just think it would end up being used as part of a typedef, all the time.
For "legitimate" cases where you need to indicate it on a per declaration
level, it seems like it would be a badly designed class and framework, and
using it correctly would be much more painful than using a class which
always uses eager destruction and helps you avoid the pitfalls by design.
Also such code would be hard to refactor. It seems mentally less demanding
to me to just know that for certain types you always have to avoid certain
scenarios.

That would cause the compiler to destroy the variable after its last named
> use.
>
> This allows template programming to actually work. If a template function
> needed to use eager destruction, then the template would express that in
> the declaration of an automatic variable. And therefore, the person writing
> that template function would know that they cannot do tricks on the
> variable like `forward_as_tuple`.
>
> Also, there still need to be clarifications on what "last use" means.
> Consider:
>
> Matrix a = ...
> for(loop)
> {
>   Matrix b = a * whatever;
>   //Do stuff with b, without using a
> }
>
> When does `a` get destroyed? I guess it would have to be after the loop,
> right? Otherwise, the compiler would have to advance the loop prematurely
> to see if `a` needs to be destroyed.
>
> How does this work with conditional branching? Or God help you, with
> `goto`?
>

Good points. For the Streamer use case it would make sense to be aggressive
about calling the destructor at the earliest possible, while for the Matrix
case it might be reasonable to wait until the next branch merge point. This
isn't our biggest point of contention right now, but we'll need to get back
to this. Thanks for bringing it up.

-- 
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/CAE7XuEWB6sT8E2bFXC1D291vKna2CLh8Z4%2Bjp3M1%3Ds5%3Dt4M2fw%40mail.gmail.com.

--94eb2c0584542c4d38053b3c7208
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_quote"><div dir=3D"ltr">On Sat, Aug 27=
, 2016 at 11:10 AM Nicol Bolas &lt;<a href=3D"mailto:jmckesson@gmail.com">j=
mckesson@gmail.com</a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote=
" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><=
div dir=3D"ltr">On Thursday, August 25, 2016 at 5:24:39 PM UTC-4, Nicolas C=
apens wrote:<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">Thanks=
 all for the initial feedback! It&#39;s clear to me now that I haven&#39;t =
defined &quot;last use&quot; very well, and giving it an accurate definitio=
n based on my limited knowledge of compiler lingo is going to be tricky.<di=
v><br></div><div>So let me take a step back and describe what real-world is=
sues I&#39;m trying to solve. The first example is one where I&#39;d like t=
he heap memory managed by an object to get freed at the same point where a =
scalar variable&#39;s register would be made available for a different vari=
able:</div></div></blockquote></div><div dir=3D"ltr"><div><br>I don&#39;t t=
hink anyone misunderstands what your <i>intended use cases</i> are. But the=
 fact is that things do not get used the way they are intended at all times=
..<br><br>Consider a basic bit of template programming:<br><br><div style=3D=
"background-color:rgb(250,250,250);border-color:rgb(187,187,187);border-sty=
le:solid;border-width:1px;word-wrap:break-word"><code><div><span style=3D"c=
olor:#000">T t </span><span style=3D"color:#660">=3D</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#660">...</span><span style=3D"colo=
r:#000"><br></span><span style=3D"color:#008">auto</span><span style=3D"col=
or:#000"> tpl </span><span style=3D"color:#660">=3D</span><span style=3D"co=
lor:#000"> forward_as_tuple</span><span style=3D"color:#660">(</span><span =
style=3D"color:#000">t</span><span style=3D"color:#660">);</span><span styl=
e=3D"color:#000"><br></span><span style=3D"color:#800">//do something with =
tpl.</span><span style=3D"color:#000"><br></span></div></code></div><br>Thi=
s code, today, works for any type `T` which can be constructed with whateve=
r ... was. Your feature would now make this code <i>suspect</i>. It would <=
i>only work</i> for `T`s that do not use &quot;eager&quot; destruction. So =
if someone wanted to instantiate this template with your `Matrix` type, thi=
s code breaks.<br></div></div></blockquote><div><br></div><div>There are al=
ready many situations in which seemingly well understood code can behave di=
fferently than expected. Copy elision, exceptions, platform-specific typede=
fs, operator overloading, and virtual functions are all known to catch peop=
le by surprise. It&#39;s an inherent property of C++ that many different th=
ings can happen behind our backs, which can also be incredibly powerful. So=
 I think eager destruction might require tossing some old assumptions out o=
f the window, but it will enable some valuable new optimizations.</div><div=
><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bor=
der-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Normal amou=
nts of compiler analysis cannot fix that. After all, the compiler doesn&#39=
;t (necessarily) know what&#39;s going on in `forward_as_tuple`. All the co=
mpiler sees is that you&#39;re passing a reference in, and you&#39;re getti=
ng at tuple&lt;T&amp;&gt; out. How could the compiler know that `tpl` conta=
ins a reference to `t`? It can&#39;t; not without doing <i>serious</i> usag=
e analysis.<br><br>And that&#39;s for a <i>simple</i> case; `forward_as_tup=
le` is a template function, so the compiler has its implementation. It coul=
d have been a non-template function that wasn&#39;t inlined. At which point=
, it requires whole program analysis to know <i>for certain</i> that the re=
turn value contains a reference to a function parameter.<br></div></div></b=
lockquote><div><br></div><div>I&#39;m not entirely convinced yet that this =
is unreasonable to be expected from a modern compiler. Destruction at the e=
nd of the scope, interprocedural register allocation, and garbage collectio=
n all have existed for decades. Isn&#39;t it time to add a new option which=
 might require some static analysis? If not now, can we have it the next ce=
ntury? Either way I feel like we&#39;re stuck while technically we&#39;re a=
lready able to do better. We just have to be willing to make the necessary =
changes to the standard, and figure out the right balance between determini=
sm, ease of use, conservatism, etc.</div><div><br></div><div>By the way, on=
e other potential way this could be solved is to not allow storing referenc=
ed to classes with eager destruction. That is, they can be function argumen=
ts, but they can&#39;t be member variables or global variables. The above c=
ode would then simply not compile and you&#39;d get a clear error message a=
bout it.</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"m=
argin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"l=
tr"><div>Remember: this is the confounding problem with temporary lifetime =
extension, when passing temporaries through functions.<br><br>Who&#39;s fau=
lt is this failure? Is it the fault of the person who wrote this template c=
ode without knowing that such a feature was going to be introduced? No, of =
course not. It has to be the fault of the person who passed `Matrix` to thi=
s template. But how could they know that `Matrix`&#39;s eager destructor wo=
uld cause the template to break?<br><br>Thus, the blame must fall on the fe=
ature itself.<br><br>Your post talks about the utility of this feature with=
 &quot;scalar types&quot;. But what you&#39;re really talking about is how =
you <i>use</i> the type. The type is safe so long as you treat it as a pure=
 value: you never get a pointer/reference to it or of its contents. But not=
e where this distinction is made. It&#39;s not made in the type&#39;s decla=
ration (you can get references to `int`, after all). It&#39;s made <i>at th=
e point of use</i>.<br></div></div></blockquote><div><br></div><div>Taking =
reference to <font face=3D"monospace">int</font> is handled by liveness ana=
lysis by treating it as an alias. And when it disappears into an unknown fu=
nction it can fall back to keeping the variable live until the end of its s=
cope. But in many cases it can still optimize register usage, and a crucial=
 part of that is knowing that there are no noticeable side effects. That&#3=
9;s a property of its type. Likewise I think that for cases where an object=
 is self-contained and we don&#39;t care when the side effects of its destr=
uction happen, that too should be a property of the type.</div><div><br></d=
iv><div>Note that I&#39;m not married to this idea. I&#39;m just trying to =
make sure you can see things my way as well before we discuss the pros and =
cons of the alternatives.</div><div>=C2=A0</div><blockquote class=3D"gmail_=
quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1=
ex"><div dir=3D"ltr"><div>The problem, as Matt has said, is that your featu=
re works at the <i>type</i> level. To make this feature work, it has to hap=
pen at the <i>usage</i> level. The person declaring that variable <i>must e=
xplicitly state</i> that they will use the type as a pure value. That they =
won&#39;t get pointers/references to itself or its contents.<br><br>The rig=
ht way to handle this is to make it a function of the object&#39;s declarat=
ion:<br><br><div 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"><c=
ode><div><span style=3D"color:#008">&lt;some_syntax&gt;</span><span style=
=3D"color:#000"> TypeName varName;</span></div></code></div></div></div></b=
lockquote><div><br></div><div>If this can be part of a typedef (like <font =
face=3D"monospace">const</font>), then that seems reasonable to me. Note th=
at I really wouldn&#39;t want to annotate the use of a <a href=3D"https://s=
wiftshader.googlesource.com/SwiftShader/+/HEAD/docs/Reactor.md">Reactor</a>=
 type at each variable declaration.</div><div><br></div><div>I just think i=
t would end up being used as part of a typedef, all the time. For &quot;leg=
itimate&quot; cases where you need to indicate it on a per declaration leve=
l, it seems like it would be a badly designed class and framework, and usin=
g it correctly would be much more painful than using a class which always u=
ses eager destruction and helps you avoid the pitfalls by design. Also such=
 code would be hard to refactor. It seems mentally less demanding to me to =
just know that for certain types you always have to avoid certain scenarios=
..</div><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0=
 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>=
That would cause the compiler to destroy the variable after its last named =
use.<br><br>This allows template programming to actually work. If a templat=
e function needed to use eager destruction, then the template would express=
 that in the declaration of an automatic variable. And therefore, the perso=
n writing that template function would know that they cannot do tricks on t=
he variable like `forward_as_tuple`.<br><br>Also, there still need to be cl=
arifications on what &quot;last use&quot; means. Consider:<br><br><div styl=
e=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);border=
-style:solid;border-width:1px;word-wrap:break-word"><code><div><span style=
=3D"color:#606">Matrix</span><span style=3D"color:#000"> a </span><span sty=
le=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">...</span><span style=3D"color:#000"><br></span><span style=
=3D"color:#008">for</span><span style=3D"color:#660">(</span><span style=3D=
"color:#000">loop</span><span style=3D"color:#660">)</span><span style=3D"c=
olor:#000"><br></span><span style=3D"color:#660">{</span><span style=3D"col=
or:#000"><br>=C2=A0 </span><span style=3D"color:#606">Matrix</span><span st=
yle=3D"color:#000"> b </span><span style=3D"color:#660">=3D</span><span sty=
le=3D"color:#000"> a </span><span style=3D"color:#660">*</span><span style=
=3D"color:#000"> whatever</span><span style=3D"color:#660">;</span><span st=
yle=3D"color:#000"><br>=C2=A0 </span><span style=3D"color:#800">//Do stuff =
with b, without using a</span><span style=3D"color:#000"><br></span><span s=
tyle=3D"color:#660">}</span><span style=3D"color:#000"><br></span></div></c=
ode></div><br>When does `a` get destroyed? I guess it would have to be afte=
r the loop, right? Otherwise, the compiler would have to advance the loop p=
rematurely to see if `a` needs to be destroyed.<br><br>How does this work w=
ith conditional branching? Or God help you, with `goto`?</div></div></block=
quote><div><br></div><div>Good points. For the Streamer use case it would m=
ake sense to be aggressive about calling the destructor at the earliest pos=
sible, while for the Matrix case it might be reasonable to wait until the n=
ext branch merge point. This isn&#39;t our biggest point of contention righ=
t now, but we&#39;ll need to get back to this. Thanks for bringing it up.</=
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/CAE7XuEWB6sT8E2bFXC1D291vKna2CLh8Z4%2=
Bjp3M1%3Ds5%3Dt4M2fw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAE7XuEWB6s=
T8E2bFXC1D291vKna2CLh8Z4%2Bjp3M1%3Ds5%3Dt4M2fw%40mail.gmail.com</a>.<br />

--94eb2c0584542c4d38053b3c7208--

.
