220 27968 <CAE7XuEVatPUpbd_UOA-wq82P-Qk2sbOVvCQwOSJhPVFojwtD7A@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: Fri, 26 Aug 2016 14:57:24 +0000
Lines: 458
Approved: news@gmane.org
Message-ID: <CAE7XuEVatPUpbd_UOA-wq82P-Qk2sbOVvCQwOSJhPVFojwtD7A@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> <371d0b28-0593-4f79-9c05-1e9540cc4e2c@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/alternative; boundary=001a1141136e14763f053afabc70
X-Trace: blaine.gmane.org 1472223462 6014 195.159.176.226 (26 Aug 2016 14:57:42 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Fri, 26 Aug 2016 14:57:42 +0000 (UTC)
To: btcrtn@gmail.com, 
	"ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBC6MN3XGLYIN7MMBXYCRUBE65KBVQ@isocpp.org Fri Aug 26 16:57:37 2016
Return-path: <std-proposals+bncBC6MN3XGLYIN7MMBXYCRUBE65KBVQ@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-qt0-f200.google.com ([209.85.216.200])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBC6MN3XGLYIN7MMBXYCRUBE65KBVQ@isocpp.org>)
	id 1bdIZb-00012K-Nv
	for gclcip-std-proposals@m.gmane.org; Fri, 26 Aug 2016 16:57:36 +0200
Original-Received: by mail-qt0-f200.google.com with SMTP id 93sf152285792qtg.1
        for <gclcip-std-proposals@m.gmane.org>; Fri, 26 Aug 2016 07:57:36 -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=stuJUsG0tlCWRc7Q9viYYmfAb9sPrZjFlP2BmKyPmVQ=;
        b=i2AEFmshlFUhHWKYrJo9yD1iKY/Sgec99l2PWwPPOJF33nI1oyFoohTCH8NVywzQAC
         6W+3Ba30NZ7ZEuhSO+2+wHd/zTvsEyNrSgc/hDislAhwsmKt1m2BEkzSVzx4D9KVkRWU
         0BElhwrzOmTbuH1CqS+wCCg3X1p8m1xlioQvsBp4y3kwNlmQeNOgKAigk0DUzLwsq8pJ
         4d6uwI9GrZy2g/GXEtVdkwYFxkhP7KpEPaoH4vsSdivqPOjYcngkoC0cTcakl1CNGkMQ
         zrxy1D2vXCKlc+Wszyy7jwZuFEdUaQ2l50VCAEsPEsj8qcgxa2kKbxia75J+GdxzIMhF
         zwrg==
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=stuJUsG0tlCWRc7Q9viYYmfAb9sPrZjFlP2BmKyPmVQ=;
        b=RAZXwzdXjbh0ML9aj6sWJ1pXbX5p+344SYpOH58Ohqem0TtTHTNkzy+3MIabqf4t09
         xC/NWiE3/B6H4HVKTIRoJRmb2+ojXqu4OToyPWU19OYVW6rKL7lBcDt3vahzXfiuehj2
         QI+dxe6cmWFgRxHDniz03NpsMVAh93EC0pVp+cgJHJ3hSHEWcgUWoCC6z6hBKzt8SQ0b
         yO4U4I57V0PcPVCSLT2tVBcXIbwpXmb96n4EqwfSJ8HP4ztqGDGOAnuqmQIGQ/l9Y4GU
         +4Ay5ukdiiseVj4go7gvrGgVl/R6mr9QCmNRzvXnXgryX17LmFgReE9BIvST2AN8JD4n
         KHvQ==
X-Gm-Message-State: AE9vXwOSYcyzyYThDww9iX88SPAyLiVat5Y/0dmbvTYcm8w8aoFgpJMTD81SdWIiqhIgXw==
X-Received: by 10.129.121.70 with SMTP id u67mr2913370ywc.2.1472223456407;
        Fri, 26 Aug 2016 07:57:36 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.157.29.207 with SMTP id w15ls3400099otw.10.gmail; Fri, 26 Aug
 2016 07:57:35 -0700 (PDT)
X-Received: by 10.200.47.253 with SMTP id m58mr3893690qta.60.1472223455474;
        Fri, 26 Aug 2016 07:57:35 -0700 (PDT)
Original-Received: from mail-qt0-x22c.google.com (mail-qt0-x22c.google.com. [2607:f8b0:400d:c0d::22c])
        by mx.google.com with ESMTPS id f62si5229007qkj.127.2016.08.26.07.57.35
        for <std-proposals@isocpp.org>
        (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
        Fri, 26 Aug 2016 07:57:35 -0700 (PDT)
Received-SPF: pass (google.com: domain of nicolas.capens@gmail.com designates 2607:f8b0:400d:c0d::22c as permitted sender) client-ip=2607:f8b0:400d:c0d::22c;
Original-Received: by mail-qt0-x22c.google.com with SMTP id 52so39053378qtq.3
        for <std-proposals@isocpp.org>; Fri, 26 Aug 2016 07:57:35 -0700 (PDT)
X-Received: by 10.200.37.252 with SMTP id f57mr3827756qtf.68.1472223455244;
 Fri, 26 Aug 2016 07:57:35 -0700 (PDT)
In-Reply-To: <371d0b28-0593-4f79-9c05-1e9540cc4e2c@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:c0d::22c 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:27968
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/27968>

--001a1141136e14763f053afabc70
Content-Type: text/plain; charset=UTF-8

On Thu, Aug 25, 2016 at 5:35 PM <btcrtn@gmail.com> wrote:

> Would it not be convenient enough to define a helper function? Would the
> following work?
>
> template<class T>
> void finish(T&& x)
> {
>     auto y{std::move(x)};
> }
>
> void f()
> {
>     MyExpensiveResource r;
>     /* code */
>     finish(r); // 'r' is not needed anymore.
>     /* code */
> }
>
>
No, that's just another way of manually calling r.~MyExpensiveResource().
When you have several of these resources it clutters up your code and
complicates making changes. Like I said before, imagine having to do it for
all your scalar variables to get good register allocation. That's
unacceptable and fortunately modern compilers have liveness analysis so
it's not a concern. But we shouldn't have to manually do it for non-basic
self-contained types either.

On Thursday, August 25, 2016 at 11:24:39 PM UTC+2, 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:
>>
>>     class Matrix
>>     {
>>     public:
>>         Matrix(size_t rows, size_t columns);
>>         auto ~Matrix();   // Eager destructor
>>         ...
>>     private:
>>         double *m;
>>     };
>>
>>     {
>>         Matrix a(10'000, 10'000) = ...;
>>         Matrix b(10'000, 10'000) = ...;
>>         Matrix c(10'000, 10'000) = ...;
>>
>>         a += b;   // Last use of b, destruct before the next line
>>         a += c;
>>      }
>>
>> The alternative of using explicit destruction is really inconvenient:
>>
>>     {
>>         Matrix a(10'000, 10'000) = ...;
>>         Matrix b(10'000, 10'000) = ...;
>>         Matrix c(10'000, 10'000) = ...;
>>
>>         a += b;
>>         b.~Matrix();
>>         a += c;
>>     }
>>
>> As is reducing the scope:
>>
>>     {
>>         Matrix a(10'000, 10'000) = ...;
>>
>>         {
>>             Matrix b(10'000, 10'000) = ...;
>>             a += b;
>>         }
>>
>>         Matrix c(10'000, 10'000) = ...;
>>         a += c;
>>     }
>>
>
>> It might not look that horrible when we're only dealing with one variable
>> that can be destructed eagerly, but it quickly gets unmanageable to
>> manually optimize code like this when using additional variables and longer
>> expressions. So I wish to be able to convey to the compiler that my Matrix
>> class is self-contained and can in have its destructor called before the
>> end of the object's scope.
>>
>> Obviously it would be a bad idea to allow anyone to retrieve the
>> Matrix::m pointer. If you want to keep access to the object's content,
>> you'd need to keep a reference to the object itself. It would be
>> unreasonable to require the compiler to determine if we're obtaining
>> references to the object's innards and use that to extend its lifetime. But
>> taking a reference to the object itself can easily be determined, just like
>> is done with scalar variables to extend their liveness range.
>>
>> A second use case I have for this is to reduce the run-time optimization
>> work of an EDSL used for JIT-compiling code: Reactor
>> <https://swiftshader.googlesource.com/SwiftShader/+/HEAD/docs/Reactor.md>.
>> The types that are used *represent* scalar variables (e.g. Int
>> represents int), but have a complex implementation to keep track of the
>> operations performed on them to later be used to generate code from. If the
>> static C++ compiler called their destructor on their last use as the scalar
>> they represent, optimizing the run-time generated code could be quicker.
>>
>> As for an example of optimizing mutex locking, take a class which takes
>> exclusive ownership of a stream so you can write contiguous data to it:
>>
>>     {
>>         Streamer s(stream);
>>         s.write("200");
>>         s.write(" OK");   // Last use, call destructor which releases
>> exclusive ownership so another thread can write something.
>>         do_something_else_before_end_of_scope();
>>     }
>>
>> Of course in this trivial case you might just write "200 OK" in one go,
>> but imagine a much lager stream of data that is composed of an unknown
>> number of parts. There would be an overhead from allocating and
>> reallocating storage for the whole. Also, if the reader of the stream can
>> handle partial data then we don't want to delay streaming out the parts.
>>
>> So I hope this illustrates what I'm after. I'm convinced there's an
>> unambiguous definition of "last use" that can provide us with the desired
>> behavior in all of the above examples, without undue burden on the
>> compiler's analysis. I think liveness analysis when treating the object as
>> a scalar would give us all we need.
>>
>> One question I have though is whether liveness analysis of scalars is a
>> "solved problem"? In other words are all optimizing compilers capable of
>> producing equivalent, deterministic liveness analysis? If not, I still
>> think a *conservative* eager destructor would be a great thing to have
>> to optimize the above use cases. I don't think determinism is strictly
>> necessary, since compilers already produce code that can behave differently
>> depending on optimizations.
>>
>> Thanks again!
>> - Nicolas
>>
>> On Thu, Aug 25, 2016 at 6:37 AM, Viacheslav Usov <via....@gmail.com>
>> wrote:
>>
>>> On Wed, Aug 24, 2016 at 8:51 PM, <nicolas...@gmail.com> wrote:
>>>
>>> > I'd like to propose a new kind of destructor that gets called after a
>>> local object's last use, instead of at the end of its scope.
>>>
>>> "Destruct after last use" is generally known as "garbage collection".
>>> There is no known deterministic solution to this general problem. This is
>>> what many other comments have been about. You can only make this
>>> deterministic if you provide some narrow definition of "last use". C++ has
>>> such a narrow definition for local objects, it is the automatic scope
>>> rules, simple and hugely successful. The question, then, is whether we
>>> really need another competing definition, and whether we really gain much
>>> with that additional complexity.
>>>
>>> Note I'm not assuming you would propose a non-deterministic definition.
>>>
>>> > The syntax for this could be an annotation of the destructor
>>> declaration with a keyword, symbol, or attribute. For example, "auto
>>> ~Object();", "volatile ~Object();", "~~Object();", or "[[eager]]
>>> ~Object();".
>>>
>>> The assumption that one can decorate a *class* definition with
>>> "destruct after last use" seems overly optimistic to me. Letting the
>>> users of the class decorate the *object* definition as such seems more
>>> reasonable.
>>>
>>> Cheers,
>>> V.
>>>
>> --
>>> You received this message because you are subscribed to a topic in the
>>> Google Groups "ISO C++ Standard - Future Proposals" group.
>>> To unsubscribe from this topic, visit
>>> https://groups.google.com/a/isocpp.org/d/topic/std-proposals/IUxA4cx8yHc/unsubscribe
>>> .
>>>
>> To unsubscribe from this group and all its topics, send an email to
>>> std-proposal...@isocpp.org.
>>> To post to this group, send email to std-pr...@isocpp.org.
>>>
>> To view this discussion on the web visit
>>> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAA7YVg3dJT3LY_L5Eg%3DZNgfqqyOcX9P%3DJVv_pXTEx6xxsoGOdg%40mail.gmail.com
>>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAA7YVg3dJT3LY_L5Eg%3DZNgfqqyOcX9P%3DJVv_pXTEx6xxsoGOdg%40mail.gmail.com?utm_medium=email&utm_source=footer>
>>> .
>>>
>>

-- 
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/CAE7XuEVatPUpbd_UOA-wq82P-Qk2sbOVvCQwOSJhPVFojwtD7A%40mail.gmail.com.

--001a1141136e14763f053afabc70
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 Thu, Aug 25=
, 2016 at 5:35 PM &lt;<a href=3D"mailto:btcrtn@gmail.com">btcrtn@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">Wou=
ld it not be convenient enough to define a helper function? Would the follo=
wing work?<br><br><div style=3D"background-color:rgb(250,250,250);border-co=
lor:rgb(187,187,187);border-style:solid;border-width:1px;word-wrap:break-wo=
rd"><code><div><span style=3D"color:#008">template</span><span style=3D"col=
or:#660">&lt;</span><span style=3D"color:#008">class</span><span style=3D"c=
olor:#000"> T</span><span style=3D"color:#660">&gt;</span><span style=3D"co=
lor:#000"><br></span><span style=3D"color:#008">void</span><span style=3D"c=
olor:#000"> finish</span><span style=3D"color:#660">(</span><span style=3D"=
color:#000">T</span><span style=3D"color:#660">&amp;&amp;</span><span style=
=3D"color:#000"> x</span><span style=3D"color:#660">)</span><span style=3D"=
color:#000"><br></span><span style=3D"color:#660">{</span><span style=3D"co=
lor:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">auto</span><s=
pan style=3D"color:#000"> y</span><span style=3D"color:#660">{</span><span =
style=3D"color:#000">std</span><span style=3D"color:#660">::</span><span st=
yle=3D"color:#000">move</span><span style=3D"color:#660">(</span><span styl=
e=3D"color:#000">x</span><span style=3D"color:#660">)};</span><span style=
=3D"color:#000"><br></span><span style=3D"color:#660">}</span><span style=
=3D"color:#000"><br><br></span><span style=3D"color:#008">void</span><span =
style=3D"color:#000"> f</span><span style=3D"color:#660">()</span><span sty=
le=3D"color:#000"><br></span><span style=3D"color:#660">{</span><span style=
=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#606">MyExpe<=
/span><span style=3D"color:#606">nsiveResource</span><span style=3D"color:#=
000"> r</span><span style=3D"color:#660">;</span><span style=3D"color:#000"=
><br>=C2=A0 =C2=A0 </span><span style=3D"color:#800">/* code */</span><span=
 style=3D"color:#000"><br>=C2=A0 =C2=A0 finish</span><span style=3D"color:#=
660">(</span><span style=3D"color:#000">r</span><span style=3D"color:#660">=
);</span><span style=3D"color:#000"> </span><span style=3D"color:#800">// &=
#39;r&#39; is not needed anymore.</span><span style=3D"color:#000"><br>=C2=
=A0 =C2=A0 </span><span style=3D"color:#800">/* code */</span><span style=
=3D"color:#000"><br></span><span style=3D"color:#660">}</span></div></code>=
</div></div><div dir=3D"ltr"><br></div></blockquote><div><br></div><div>No,=
 that&#39;s just another way of manually calling r.~MyExpensiveResource(). =
When you have several of these resources it clutters up your code and compl=
icates making changes. Like I said before, imagine having to do it for all =
your scalar variables to get good register allocation. That&#39;s unaccepta=
ble and fortunately modern compilers have liveness analysis so it&#39;s not=
 a concern. But we shouldn&#39;t have to manually do it for non-basic self-=
contained types either.</div><div><br></div><blockquote class=3D"gmail_quot=
e" 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 11:24:39 PM UTC+2, Nicolas=
 Capens wrote:</div><div dir=3D"ltr"><blockquote class=3D"gmail_quote" styl=
e=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 m=
e now that I haven&#39;t defined &quot;last use&quot; very well, and giving=
 it an accurate definition based on my limited knowledge of compiler lingo =
is going to be tricky.<div><br></div><div>So let me take a step back and de=
scribe what real-world issues I&#39;m trying to solve. The first example is=
 one where I&#39;d like the heap memory managed by an object to get freed a=
t the same point where a scalar variable&#39;s register would be made avail=
able for a different variable:</div><div><br></div><div><font face=3D"monos=
pace">=C2=A0 =C2=A0 class Matrix</font></div><div><font face=3D"monospace">=
=C2=A0 =C2=A0 {</font></div><div><font face=3D"monospace">=C2=A0 =C2=A0 pub=
lic:</font></div><div><font face=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =
Matrix(size_t rows, size_t columns);</font></div><div><font face=3D"monospa=
ce">=C2=A0 =C2=A0 =C2=A0 =C2=A0 auto ~Matrix(); =C2=A0 // Eager destructor<=
/font></div><div><font face=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 ...</=
font></div><div><font face=3D"monospace">=C2=A0 =C2=A0 private:</font></div=
><div><font face=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 double *m;</font=
></div><div><font face=3D"monospace">=C2=A0 =C2=A0 };</font></div><div><fon=
t face=3D"monospace"><br></font></div><div><font face=3D"monospace">=C2=A0 =
=C2=A0 {</font></div><div><font face=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 Matrix a(10&#39;000, 10&#39;000) =3D ...;</font></div><div><font face=
=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 Matrix b(10&#39;000, 10&#39;000)=
 =3D ...;<br></font></div><div><font face=3D"monospace">=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 Matrix c(10&#39;000, 10&#39;000) =3D ...;<br></font></div><div><=
font face=3D"monospace"><br></font></div><div><font face=3D"monospace">=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 a=C2=A0+=3D b; =C2=A0 // Last use of b, destruct b=
efore the next line</font></div><div><font face=3D"monospace">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 a=C2=A0+=3D c;</font></div><div><font face=3D"monospace">=C2=
=A0 =C2=A0 =C2=A0}</font></div><div><br></div></div></blockquote></div><div=
 dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-lef=
t:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div =
dir=3D"ltr"><div>The alternative of using explicit destruction is really in=
convenient:</div><div><br></div><div><div><font face=3D"monospace">=C2=A0 =
=C2=A0 {</font></div><div><font face=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 Matrix a(10&#39;000, 10&#39;000) =3D ...;</font></div><div><font face=
=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 Matrix b(10&#39;000, 10&#39;000)=
 =3D ...;<br></font></div><div><font face=3D"monospace">=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 Matrix c(10&#39;000, 10&#39;000) =3D ...;<br></font></div><div><=
font face=3D"monospace"><br></font></div><div><font face=3D"monospace">=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 a=C2=A0+=3D b;</font></div><div><font face=3D"mono=
space">=C2=A0 =C2=A0 =C2=A0 =C2=A0 b.~Matrix();</font></div><div><font face=
=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 a=C2=A0+=3D c;</font></div><div>=
<font face=3D"monospace">=C2=A0 =C2=A0 }</font></div></div><div><br></div><=
div>As is reducing the scope:</div><div><br></div><div><div><font face=3D"m=
onospace">=C2=A0 =C2=A0 {</font></div><div><font face=3D"monospace">=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 Matrix a(10&#39;000, 10&#39;000) =3D ...;</font></div>=
<div><font face=3D"monospace"><br></font></div><div><font face=3D"monospace=
">=C2=A0 =C2=A0 =C2=A0 =C2=A0 {</font></div><div><font face=3D"monospace">=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Matrix b(10&#39;000, 10&#39;000) =
=3D ...;</font></div><div><font face=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 a=C2=A0+=3D b;</font></div><div><font face=3D"monospace">=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 }</font></div><div><font face=3D"monospace"><br=
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 Matrix c(10&#39;000, 10&#39;000) =3D ...;=C2=
=A0=C2=A0<br></font></div><div><font face=3D"monospace">=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 a=C2=A0+=3D c;</font></div><div><font face=3D"monospace">=C2=A0 =
=C2=A0 }</font></div></div></div></div></blockquote></div><div dir=3D"ltr">=
<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;borde=
r-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div dir=3D"ltr"><=
div><div><br></div><div>It might not look that horrible when we&#39;re only=
 dealing with one variable that can be destructed eagerly, but it quickly g=
ets unmanageable to manually optimize code like this when using additional =
variables and longer expressions. So I wish to be able to convey to the com=
piler that my Matrix class is self-contained and can in have its destructor=
 called before the end of the object&#39;s scope.</div><div><br></div><div>=
Obviously it would be a bad idea to allow anyone to retrieve the Matrix::m =
pointer. If you want to keep access to the object&#39;s content, you&#39;d =
need to keep a reference to the object itself. It would be unreasonable to =
require the compiler to determine if we&#39;re obtaining references to the =
object&#39;s innards and use that to extend its lifetime. But taking a refe=
rence to the object itself can easily be determined, just like is done with=
 scalar variables to extend their liveness range.</div><div><br></div><div>=
A second use case I have for this is to reduce the run-time optimization wo=
rk of an EDSL used for JIT-compiling code: <a href=3D"https://swiftshader.g=
ooglesource.com/SwiftShader/+/HEAD/docs/Reactor.md" rel=3D"nofollow" target=
=3D"_blank">Reactor</a>. The types that are used=C2=A0<i>represent</i> scal=
ar variables (e.g. <font face=3D"monospace">Int</font> represents <font fac=
e=3D"monospace">int</font>), but have a complex implementation to keep trac=
k of the operations performed on them to later be used to generate code fro=
m. If the static C++ compiler called their destructor on their last use as =
the scalar they represent, optimizing the run-time generated code could be =
quicker.</div><div><br></div><div>As for an example of optimizing mutex loc=
king, take a class which takes exclusive ownership of a stream so you can w=
rite contiguous data to it:</div><div><br></div><div><font face=3D"monospac=
e">=C2=A0 =C2=A0 {</font></div><div><font face=3D"monospace">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 Streamer s(stream);</font></div><div><font face=3D"monospace"=
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 s.write(&quot;200&quot;);</font></div><div><fo=
nt face=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 s.write(&quot; OK&quot;);=
 =C2=A0 // Last use, call destructor which releases exclusive ownership so =
another thread can write something.</font></div><div><font face=3D"monospac=
e">=C2=A0 =C2=A0 =C2=A0 =C2=A0 do_something_else_before_end_of_scope();</fo=
nt></div><div><font face=3D"monospace">=C2=A0 =C2=A0 }</font></div><div><br=
></div><div>Of course in this trivial case you might just write &quot;200 O=
K&quot; in one go, but imagine a much lager stream of data that is composed=
 of an unknown number of parts. There would be an overhead from allocating =
and reallocating storage for the whole. Also, if the reader of the stream c=
an handle partial data then we don&#39;t want to delay streaming out the pa=
rts.</div><div><br></div><div>So I hope this illustrates what I&#39;m after=
.. I&#39;m convinced there&#39;s an unambiguous definition of &quot;last use=
&quot; that can provide us with the desired behavior in all of the above ex=
amples, without undue burden on the compiler&#39;s analysis. I think livene=
ss analysis when treating the object as a scalar would give us all we need.=
</div><div><br></div><div>One question I have though is whether liveness an=
alysis of scalars is a &quot;solved problem&quot;? In other words are all o=
ptimizing compilers capable of producing equivalent, deterministic liveness=
 analysis? If not, I still think a <i>conservative</i> eager destructor wou=
ld be a great thing to have to optimize the above use cases. I don&#39;t th=
ink determinism is strictly necessary, since compilers already produce code=
 that can behave differently depending on optimizations.</div><div><br></di=
v><div>Thanks again!</div><div>- Nicolas</div><div><br></div></div></div></=
div></blockquote></div><div dir=3D"ltr"><blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:=
1ex"><div dir=3D"ltr"><div dir=3D"ltr"><div><div><div class=3D"gmail_quote"=
>On Thu, Aug 25, 2016 at 6:37 AM, Viacheslav Usov <span dir=3D"ltr">&lt;<a =
rel=3D"nofollow">via....@gmail.com</a>&gt;</span> wrote:<br><blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid =
rgb(204,204,204);padding-left:1ex"></blockquote></div></div></div></div></d=
iv></blockquote></div><div dir=3D"ltr"><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1=
ex"><div dir=3D"ltr"><div dir=3D"ltr"><div><div><div class=3D"gmail_quote">=
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div><sp=
an><div class=3D"gmail_quote">On Wed, Aug 24, 2016 at 8:51 PM,  <span dir=
=3D"ltr">&lt;<a rel=3D"nofollow">nicolas...@gmail.com</a>&gt;</span> wrote:=
</div><div class=3D"gmail_quote"><br></div><div class=3D"gmail_quote">&gt;=
=C2=A0<span style=3D"font-size:12.8px">I&#39;d like to propose a new kind o=
f destructor that gets called after a local object&#39;s last use, instead =
of at the end of its scope.</span></div><div class=3D"gmail_quote"><br></di=
v></span><div class=3D"gmail_quote"><span style=3D"line-height:17px">&quot;=
Destruct after last use&quot; is generally known as &quot;garbage collectio=
n&quot;. There is no known deterministic solution to this general problem. =
This is what many other comments have been about. You can only make this de=
terministic if you provide some narrow definition of &quot;last use&quot;. =
C++ has such a narrow definition for local objects, it is the automatic sco=
pe rules, simple and hugely successful. The question, then, is whether we r=
eally need another=C2=A0competing=C2=A0definition, and whether we really ga=
in much with that additional complexity.</span><br></div><div class=3D"gmai=
l_quote"><span style=3D"line-height:17px"><br></span></div><div class=3D"gm=
ail_quote"><span style=3D"line-height:17px">Note I&#39;m not assuming you w=
ould propose a non-deterministic=C2=A0definition.</span></div><span><div cl=
ass=3D"gmail_quote"><br></div><div class=3D"gmail_quote">&gt; The s<span st=
yle=3D"line-height:17px">yntax for this could be an annotation of the destr=
uctor declaration with a keyword, symbol, or attribute. For example, &quot;=
auto ~Object();&quot;, &quot;volatile ~Object();&quot;, &quot;~~Object();&q=
uot;, or &quot;[[eager]] ~Object();&quot;.</span></div><div class=3D"gmail_=
quote"><span style=3D"line-height:17px"><br></span></div></span><div class=
=3D"gmail_quote"><span style=3D"line-height:17px">The assumption that one c=
an decorate a <i>class</i> definition with &quot;destruct after last use&qu=
ot; seems overly optimistic to me. </span>Letting the users of the class de=
corate the <i>object</i> definition as such seems more reasonable.<br></div=
><div class=3D"gmail_quote"><br></div><div class=3D"gmail_quote">Cheers,<br=
></div><div class=3D"gmail_quote">V.</div></div></div></blockquote></div></=
div></div></div></div></blockquote></div><div dir=3D"ltr"><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr"><div dir=3D"ltr"><div><div><div cla=
ss=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0p=
x 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span>

<p></p>

-- <br>
You received this message because you are subscribed to a topic in the Goog=
le Groups &quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/IUxA4cx8yHc/unsubscribe" rel=3D"nofollow=
" target=3D"_blank">https://groups.google.com/a/isocpp.org/d/topic/std-prop=
osals/IUxA4cx8yHc/unsubscribe</a>.<br></span></blockquote></div></div></div=
></div></div></blockquote></div><div dir=3D"ltr"><blockquote class=3D"gmail=
_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr"><div dir=3D"ltr"><div><div><div class=3D"gma=
il_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8=
ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span>
To unsubscribe from this group and all its topics, send an email to <a rel=
=3D"nofollow">std-proposal...@isocpp.org</a>.<br>
To post to this group, send email to <a rel=3D"nofollow">std-pr...@isocpp.o=
rg</a>.<br></span></blockquote></div></div></div></div></div></blockquote><=
/div><div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin:0;m=
argin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"l=
tr"><div dir=3D"ltr"><div><div><div class=3D"gmail_quote"><blockquote class=
=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rg=
b(204,204,204);padding-left:1ex">
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAA7YVg3dJT3LY_L5Eg%3DZNgfqqyOcX9P%3D=
JVv_pXTEx6xxsoGOdg%40mail.gmail.com?utm_medium=3Demail&amp;utm_source=3Dfoo=
ter" rel=3D"nofollow" target=3D"_blank">https://groups.google.com/a/isocpp.=
org/d/msgid/std-proposals/CAA7YVg3dJT3LY_L5Eg%3DZNgfqqyOcX9P%3DJVv_pXTEx6xx=
soGOdg%40mail.gmail.com</a>.<br>
</blockquote></div></div></div></div></div></blockquote></div></blockquote>=
</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/CAE7XuEVatPUpbd_UOA-wq82P-Qk2sbOVvCQw=
OSJhPVFojwtD7A%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAE7XuEVatPUpbd_U=
OA-wq82P-Qk2sbOVvCQwOSJhPVFojwtD7A%40mail.gmail.com</a>.<br />

--001a1141136e14763f053afabc70--

.
