220 28038 <a3b05215-bde3-4200-8623-eda046747d5a@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: Specifier to cause the destructor to be called at
 last use instead of end of scope
Date: Mon, 29 Aug 2016 21:55:35 -0700 (PDT)
Lines: 275
Approved: news@gmane.org
Message-ID: <a3b05215-bde3-4200-8623-eda046747d5a@isocpp.org>
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> <e94c3ab8-e064-4dcb-a702-3999a877d264@isocpp.org>
 <CAE7XuEWSecp0fS+6m84rF6+9cBcy5yXJL3SOPbUqEXGj9YfffQ@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_4479_1205184019.1472532936079"
X-Trace: blaine.gmane.org 1472532947 21516 195.159.176.226 (30 Aug 2016 04:55:47 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Tue, 30 Aug 2016 04:55:47 +0000 (UTC)
Cc: jmckesson@gmail.com, nicolas.capens@gmail.com
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBCEKFTV6ZUMBBSNDSS7AKGQEFR7WLCA@isocpp.org Tue Aug 30 06:55:42 2016
Return-path: <std-proposals+bncBCEKFTV6ZUMBBSNDSS7AKGQEFR7WLCA@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-qk0-f200.google.com ([209.85.220.200])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBCEKFTV6ZUMBBSNDSS7AKGQEFR7WLCA@isocpp.org>)
	id 1beb5I-0004s0-Ga
	for gclcip-std-proposals@m.gmane.org; Tue, 30 Aug 2016 06:55:40 +0200
Original-Received: by mail-qk0-f200.google.com with SMTP id i2sf23551474qke.2
        for <gclcip-std-proposals@m.gmane.org>; Mon, 29 Aug 2016 21:55:41 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=date:from:to:cc:message-id:in-reply-to:references:subject
         :mime-version:x-original-sender:reply-to:precedence:mailing-list
         :list-id:x-spam-checked-in-group:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=UYt5jOBSxmuV5JFC6dwE8oKCOWV9jlIBno4bxutvTe8=;
        b=XYkgKXDqXne19MRbuOjpoqtBq4CMdmAeDdCUoX+xWMUeX0lQfskmQWV/z1dJFp8irW
         N561/sHNSR100D7VLEDpSV9A64cIjMrb3eJ8QvF4JYi3rDxQRP8Vr82fQSuxNw9E7l3z
         rq/lRllvuhb850uYb3OplKx9D4bRLrjr8NJm3VSLjJvWqjEArOi04oAO1zC3pBUvSVgW
         s+joaIAsK63knT3UY/iAsJM7be8vNvXeB8Z3He2TvpL5YqQz2X1e5UM2bAlX6B5+2+Gp
         UPY+Nb+NLzIFcVGFyiU8YWPO7atkojBNfgUF1+pt8SWbbLYwuxSgL6XLmsuxO/+gNZaD
         ovtA==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20120113;
        h=date:from:to:cc:message-id:in-reply-to:references:subject
         :mime-version:x-original-sender:reply-to:precedence:mailing-list
         :list-id:x-spam-checked-in-group:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=UYt5jOBSxmuV5JFC6dwE8oKCOWV9jlIBno4bxutvTe8=;
        b=DEzS+Ld2vS2lySVUj9zhEg1pIIYcenlMyyJHm5viM9Bymf28kxa4iXArvkMnQHoGzS
         Y8D8Sa4Na70QOXceBPpwGMycRQSukDRjxd4kBPY8mZMHvO5iuUvyDm4LDt0X5ISHhc9f
         qxk+YTl3vcnEZK+LAumvHQO5Yk9V6YT5hTXEXuHgVuL+FEwPstHcSxuQ9J3KWNOAqyCo
         gvsE63giQNO/Z/+63Kp8m/fXoiLkcBzGp6iSnfNOJ+dBDKiokxGLByoOGv3SfawHQwra
         zGSqJjlF/AEda4dfXJderUh7qmIcDszsNqc81X0aA2K1vyDeGInlWEUlJOBQ+yfAOtTy
         PL2A==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:date:from:to:cc:message-id:in-reply-to
         :references:subject:mime-version:x-original-sender:reply-to
         :precedence:mailing-list:list-id:x-spam-checked-in-group:list-post
         :list-help:list-archive:list-subscribe:list-unsubscribe;
        bh=UYt5jOBSxmuV5JFC6dwE8oKCOWV9jlIBno4bxutvTe8=;
        b=ccw8En9ZHfAWJtD0OZsTGtCgjEh3zu8rSDp9yM8Y1n8ePZoC4+wxdUCe2qnOSYZHOx
         B7Y0dsP2xs2xzurRjUj1UfWCwnUx1zb/86/+93SqPUDFDZzatVJ2EQ6TsPf5/j8SpFtt
         guZxLyaSB5Rb/3rYT4yTG41OhbveGrYMHTnta5zu3FS0hUWbP/WUmJzvWezfQW84ZIhy
         bzxjnEM6GgarPWIj3Mz+UnXl71eEW4fPY9Xfbkn7TsHPfe1l1mI/pkPUg8P3jE9r8Shl
         S9tv5kfq/aUt7vtVkdS4NhmgdlvEO4JXHw2WHbQkut/Zfq49nslRhU8UjIddofWM0QBR
         SLPg==
X-Gm-Message-State: AE9vXwMM5FCKQC+uBicDDONSvVkFF5LyKSRDkhP9q425CO5WbRy1qf9hM6cO4/2Xy+cdyw==
X-Received: by 10.200.46.149 with SMTP id h21mr1367215qta.3.1472532941187;
        Mon, 29 Aug 2016 21:55:41 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.36.115.7 with SMTP id y7ls604683itb.16.gmail; Mon, 29 Aug 2016
 21:55:37 -0700 (PDT)
X-Received: by 10.36.228.11 with SMTP id o11mr197894ith.3.1472532937528;
        Mon, 29 Aug 2016 21:55:37 -0700 (PDT)
In-Reply-To: <CAE7XuEWSecp0fS+6m84rF6+9cBcy5yXJL3SOPbUqEXGj9YfffQ@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-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:28038
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/28038>

------=_Part_4479_1205184019.1472532936079
Content-Type: multipart/alternative; 
	boundary="----=_Part_4480_1457954864.1472532936080"

------=_Part_4480_1457954864.1472532936080
Content-Type: text/plain; charset=UTF-8

On Monday, August 29, 2016 at 11:07:09 PM UTC-4, Nicolas Capens wrote:
>
> On Sat, Aug 27, 2016 at 4:54 PM Nicol Bolas <jmck...@gmail.com 
> <javascript:>> wrote:
>
>> The other advantage to making eager destruction a function of how the 
>> object is declared is that it can be used with *anything*. We couldn't 
>> declare that any currently existing standard library types use eager 
>> destruction. And yet, there's no reason why we couldn't use it with most 
>> such types, so long as the uses of those objects don't violate the "never 
>> get pointers/references" rule.
>>
>> If eager destruction is as important as you believe it is, then I 
>> shouldn't have to write a wrapper type around `vector` or `deque` or 
>> whatever just to get that behavior. Users of `vector` have just as much 
>> right to benefit from said optimization as users of your class do (so long 
>> as they follow the rules).
>>
>
> That's indeed an attractive argument. I'm still a bit wary though that 
> using a new feature like eager destruction with a legacy class could more 
> easily lead to bugs. For example std::string too easily allows access to 
> its internal storage.
>

Which is perfectly valid, so long as you use the object correctly:

[[eager-destruct]] std::string str = std::to_string(53.4f);
std::cout << str;
//done with `str`.

Correct behavior in accord with eager destruction is defined by how you *use 
the object*, not how the type is written.

And because its defined at the point of use, the person using the feature 
likely knows what its rules are and knows how to abide by them.

Also, if eager destructions isn't fully deterministic but implementation 
> dependent, then something that might work fine on one compiler can cause 
> issues on another.
>

And how's that different from any other form of undefined behavior?

The rule is very simple: it is UB to do anything which requires that an 
automatic variable's destructor has not been called after the last use of 
that variable's name in the control flow of that variable's scope.

Also, you have yet to prove that you can define "last use" in a "fully 
deterministic" way. Which is why the attribute approach is better; it 
guarantees *nothing*. It allows compilers to provide quick destruction in 
simple cases, but it doesn't force them into doing crazy analysis of 
conditional logic. They can if they want, but that's all QOI.

This is somewhat less likely when a class was designed with eager 
> destruction in mind in the first place. 
>

> Anyway, I'm not against providing the user with more options. Perhaps we 
> can simply allow to specify eager destruction both at the class level and 
> per declaration.
>

I don't know if you're understanding why putting it on the type is a bad 
thing. The reasoning has been scattered across this thread, so let me try 
to collate it here.

To put this property on the type itself forces every user of that type to 
abide by certain rules. The type, from the perspective of the user, has 
transparently changed the rules of object lifetime, relative to any other 
type.

The compiler cannot *verify* that you are following those rules (see 
below). If you break the rules, the compiler cannot detect it in every 
case. Therefore, it falls on the people using that type to abide by those 
rules. This places a burden on the user of the type. They have to know that 
it is a type with wonky lifetime rules and make sure to abide by its rules.

Furthermore, template code already exists which does not abide by these 
rules. And there is no way for them to have been written to detect a 
property that did not know existed when they were written. Users must 
therefore know the implementation details of *any template code* that they 
use this type with, avoiding instantiating a template with one of these 
"eager" objects lest the template code break them.

All of this creates a general atmosphere of fragility in your programming 
environment. You have to abide by arcane rules, which the compiler cannot 
detect violations of, just to use some type as an automatic variable. These 
are rules that you did not ask for. That you did not agree to use.

And it is all done for an alleged performance gain that *may not matter to 
you or your program* (premature optimization is premature).

By putting it on the object declaration, we give people great power. They 
can choose to use it where they want. But when they exercise that great 
power, they are also willingly choosing to assume the great 
responsibilities that come with it.

And the people who have absolutely no need for it and don't care, they can 
use standard object lifetime rules. They don't need the burden of those 
responsibilities, so they don't use the feature. Who are you to say that 
they should *have to*?



*Below*No amount of static analysis can pierce a DLL/SO boundary. Code that 
isn't even *available* to the linker cannot possibly be analyzed at compile 
time. Static analysis is also confounded by non-static constructs, like 
function pointers and virtual functions. Static analysis after all is 
*static*. Programs are not static constructs.

So even in the best possible case, where the compiler/linker has access to 
all of the code, it is *impossible* to know exactly how every function will 
use a type. It cannot know whether a return value references a parameter or 
not.

Not in the general case. And if it can't do it in the general case, then we 
cannot *require* that it be done.

-- 
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/a3b05215-bde3-4200-8623-eda046747d5a%40isocpp.org.

------=_Part_4480_1457954864.1472532936080
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Monday, August 29, 2016 at 11:07:09 PM UTC-4, Nicolas C=
apens wrote:<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 class=3D"gmail_quote"><div dir=3D"ltr">On Sat, Aug 27, 2016 at 4:54 PM =
Nicol Bolas &lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-ma=
ilto=3D"DNlBEMXyEQAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;java=
script:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;ret=
urn true;">jmck...@gmail.com</a>&gt; wrote:<br></div><blockquote class=3D"g=
mail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><div dir=3D"ltr">The other advantage to making eager destruction a=
 function of how the object is declared is that it can be used with <i>anyt=
hing</i>. We couldn&#39;t declare that any currently existing standard libr=
ary types use eager destruction. And yet, there&#39;s no reason why we coul=
dn&#39;t use it with most such types, so long as the uses of those objects =
don&#39;t violate the &quot;never get pointers/references&quot; rule.<br><b=
r>If eager destruction is as important as you believe it is, then I shouldn=
&#39;t have to write a wrapper type around `vector` or `deque` or whatever =
just to get that behavior. Users of `vector` have just as much right to ben=
efit from said optimization as users of your class do (so long as they foll=
ow the rules).</div></blockquote><div><br></div><div>That&#39;s indeed an a=
ttractive argument. I&#39;m still a bit wary though that using a new featur=
e like eager destruction with a legacy class could more easily lead to bugs=
.. For example std::string too easily allows access to its internal storage.=
</div></div></div></blockquote><div><br>Which is perfectly valid, so long a=
s you use the object correctly:<br><br><div class=3D"prettyprint" style=3D"=
background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); bor=
der-style: solid; border-width: 1px; word-wrap: break-word;"><code class=3D=
"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">[[</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">eager</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">-</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">destruct</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">]]</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> std<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">string</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> str </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> std</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">to_string</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">(</span><span style=3D"color: #066;" class=3D"styl=
ed-by-prettify">53.4f</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br>std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">cout </s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;&lt;</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> str</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"co=
lor: #800;" class=3D"styled-by-prettify">//done with `str`.</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br></span></div></code></=
div><br>Correct behavior in accord with eager destruction is defined by how=
 you <i>use the object</i>, not how the type is written.<br><br>And because=
 its defined at the point of use, the person using the feature likely knows=
 what its rules are and knows how to abide by them.<br><br></div><blockquot=
e class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: =
1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div class=3D"gmail_quo=
te"><div>Also, if eager destructions isn&#39;t fully deterministic but impl=
ementation dependent, then something that might work fine on one compiler c=
an cause issues on another.</div></div></div></blockquote><div><br>And how&=
#39;s that different from any other form of undefined behavior?<br><br>The =
rule is very simple: it is UB to do anything which requires that an automat=
ic variable&#39;s destructor has not been called after the last use of that=
 variable&#39;s name in the control flow of that variable&#39;s scope.<br><=
br>Also, you have yet to prove that you can define &quot;last use&quot; in =
a &quot;fully deterministic&quot; way. Which is why the attribute approach =
is better; it guarantees <i>nothing</i>. It allows compilers to provide qui=
ck destruction in simple cases, but it doesn&#39;t force them into doing cr=
azy analysis of conditional logic. They can if they want, but that&#39;s al=
l QOI.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><div class=3D"gmail_quote"><div>This is somewhat less likely when =
a class was designed with eager destruction in mind in the first place. <br=
></div></div></div></blockquote><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"><div class=3D"gmail_quote"><div><br></div><div>Anyway, I=
&#39;m not against providing the user with more options. Perhaps we can sim=
ply allow to specify eager destruction both at the class level and per decl=
aration.</div></div></div></blockquote><div><br>I don&#39;t know if you&#39=
;re understanding why putting it on the type is a bad thing. The reasoning =
has been scattered across this thread, so let me try to collate it here.<br=
><br>To put this property on the type itself forces every user of that type=
 to abide by certain rules. The type, from the perspective of the user, has=
 transparently changed the rules of object lifetime, relative to any other =
type.<br><br>The compiler cannot <i>verify</i> that you are following those=
 rules (see below). If you break the rules, the compiler cannot detect it i=
n every case. Therefore, it falls on the people using that type to abide by=
 those rules. This places a burden on the user of the type. They have to kn=
ow that it is a type with wonky lifetime rules and make sure to abide by it=
s rules.<br><br>Furthermore, template code already exists which does not ab=
ide by these rules. And there is no way for them to have been written to de=
tect a property that did not know existed when they were written. Users mus=
t therefore know the implementation details of <i>any template code</i> tha=
t they use this type with, avoiding instantiating a template with one of th=
ese &quot;eager&quot; objects lest the template code break them.<br><br>All=
 of this creates a general atmosphere of fragility in your programming envi=
ronment. You have to abide by arcane rules, which the compiler cannot detec=
t violations of, just to use some type as an automatic variable. These are =
rules that you did not ask for. That you did not agree to use.<br><br>And i=
t is all done for an alleged performance gain that <i>may not matter to you=
 or your program</i> (premature optimization is premature).<br><br>By putti=
ng it on the object declaration, we give people great power. They can choos=
e to use it where they want. But when they exercise that great power, they =
are also willingly choosing to assume the great responsibilities that come =
with it.<br><br>And the people who have absolutely no need for it and don&#=
39;t care, they can use standard object lifetime rules. They don&#39;t need=
 the burden of those responsibilities, so they don&#39;t use the feature. W=
ho are you to say that they should <i>have to</i>?<br><br><u><b>Below<br><b=
r></b></u>No amount of static analysis can pierce a DLL/SO boundary. Code t=
hat isn&#39;t even <i>available</i> to the linker cannot possibly be analyz=
ed at compile time. Static analysis is also confounded by non-static constr=
ucts, like function pointers and virtual functions. Static analysis after a=
ll is <i>static</i>. Programs are not static constructs.<br><br>So even in =
the best possible case, where the compiler/linker has access to all of the =
code, it is <i>impossible</i> to know exactly how every function will use a=
 type. It cannot know whether a return value references a parameter or not.=
<br><br>Not in the general case. And if it can&#39;t do it in the general c=
ase, then we cannot <i>require</i> that it be done.<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/a3b05215-bde3-4200-8623-eda046747d5a%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/a3b05215-bde3-4200-8623-eda046747d5a=
%40isocpp.org</a>.<br />

------=_Part_4480_1457954864.1472532936080--

------=_Part_4479_1205184019.1472532936079--

.
