220 28019 <85dfd0dc-bf1a-4fa8-81f5-2b36e8f6465c@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 11:46:36 -0700 (PDT)
Lines: 398
Approved: news@gmane.org
Message-ID: <85dfd0dc-bf1a-4fa8-81f5-2b36e8f6465c@isocpp.org>
References: <ec2e95cc-3ef0-435b-aaf9-13e982c4583e@isocpp.org>
 <CANh8DEm-3RG1u99c6dUqSgthiVR_wE6FOfzHGbKuMqZBDptcOg@mail.gmail.com>
 <db0b8dd4-5cd9-4d4d-b7a8-95d6ab15ad8c@isocpp.org> <4387866d-169e-44a8-a858-d9aa96d54680@isocpp.org>
 <CAE7XuEXEV=xKW_g-1h1MFbg-3Fya83xkcoqGePvPbBPMTXPamA@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_703_2069452979.1472496396996"
X-Trace: blaine.gmane.org 1472496414 19123 195.159.176.226 (29 Aug 2016 18:46:54 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Mon, 29 Aug 2016 18:46:54 +0000 (UTC)
Cc: jmckesson@gmail.com, calabrese@x.team, nicolas.capens@gmail.com
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBCEKFTV6ZUMBBDUGSK7AKGQEUJBPHTQ@isocpp.org Mon Aug 29 20:46:44 2016
Return-path: <std-proposals+bncBCEKFTV6ZUMBBDUGSK7AKGQEUJBPHTQ@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-it0-f72.google.com ([209.85.214.72])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBCEKFTV6ZUMBBDUGSK7AKGQEUJBPHTQ@isocpp.org>)
	id 1beRZy-0003iO-9S
	for gclcip-std-proposals@m.gmane.org; Mon, 29 Aug 2016 20:46:42 +0200
Original-Received: by mail-it0-f72.google.com with SMTP id c76sf7441460itd.2
        for <gclcip-std-proposals@m.gmane.org>; Mon, 29 Aug 2016 11:46:43 -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=FBEcrRAatHiclgUM/p8EdG2jhNaLUsImPOSTKeQ9l1c=;
        b=BsBOxJTjPvJyQurhl3WfZQ06yIECTHywyhSS9Jb5K1Bmgq94M3xlX/cHonqaxNDW7u
         KQboDEA0oMeFdMmPRGC3J28J7O0fz+rvAjTfcAs86vW59h5HW8raSNejQA1ZYubxZoi2
         xP0fNdoRNpoxy5iE33b9PEBTwR7HQzhErc8/rnsilcmrZ2sEnMKko89rSHA95PfQ7Feq
         nOTeXr7mJXabU5Zl1eAZ4wXlYDz0HTUuSfu6u2L3gY1Tx6i1JM37/adQoQK7wrq/4MSm
         Pj9MPRpRpUcOcQJWKvZ7q7yIrhxiVy6U51YXinXsIofr8uqPMeOkzPBFsFEvikmiVEjK
         VnyQ==
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=FBEcrRAatHiclgUM/p8EdG2jhNaLUsImPOSTKeQ9l1c=;
        b=DgzhNLBlQ3i7F2NawVqnLjXY0X9JL9pDbMC1SstHSncKfgtSeLCh4JR7vgt/kUMqGz
         7DKyVKO1zZmaasFGfyuUUoUu6yEE2IQ6PLidvRKtwCUrS2kU/lVIsiCDTcPA1Yy47AJe
         L2jUhCAPp81nV5Lc0QTscM0kvMgSHtaE9E4AGssJslLGXVJAxy4ds2HcxqmlDjNJdAyi
         01SEn6KTQrecAiLFhoL2EyzI8orv6xc8Qw4L9KtjFCqGs7mzEWTVBPEtgh9BBcX/Z71p
         HOembbJqesO43huLihPGb/dFxuwKdglW9OlqiBKlxo1nGi7jd6bdnnwBXWPkFE2aZ2f8
         bkeA==
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=FBEcrRAatHiclgUM/p8EdG2jhNaLUsImPOSTKeQ9l1c=;
        b=KxwJIG3Gyibui4A35HYKylM+RdcyaRWfVNqJUxyn3y5hiniqelrv61lR7ZtPrEFMsI
         XFJPqCxXQX/Rpn/name2Woe3t72tKHrYQ+Pjbhi4eqfryjVihJ1jIdwWuKj0dXlhdr2z
         ahnhA3awQO0cR4wGxr4iBPwMQLnxdGbyJsBwcuHygqZL+93Vv+ovrkDnj9UmPCUnFwS/
         x74y7GY9GLTDcIruOltww/vd5fRMpbkkmYcgJrr9rHjxfx79crq46Z14R4Tl7OSpF6gs
         tfhlDFjflXDs0N2O/DYAvaM5YWVqwvw5bynG9V/R2a45jlip17BVQe+LIdtcbjLWmofe
         mTGw==
X-Gm-Message-State: AE9vXwNgU3IpeGmFcVZE+zut7pCNAXfcMKhi6yyc8A/J999k/W3qqDczIcINGqB2c0/mOQ==
X-Received: by 10.36.124.80 with SMTP id a77mr75583itd.1.1472496403013;
        Mon, 29 Aug 2016 11:46:43 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.36.228.7 with SMTP id o7ls590941ith.11.gmail; Mon, 29 Aug 2016
 11:46:38 -0700 (PDT)
X-Received: by 10.36.103.4 with SMTP id u4mr428979itc.9.1472496398284;
        Mon, 29 Aug 2016 11:46:38 -0700 (PDT)
In-Reply-To: <CAE7XuEXEV=xKW_g-1h1MFbg-3Fya83xkcoqGePvPbBPMTXPamA@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:28019
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/28019>

------=_Part_703_2069452979.1472496396996
Content-Type: multipart/alternative; 
	boundary="----=_Part_704_1123617417.1472496396997"

------=_Part_704_1123617417.1472496396997
Content-Type: text/plain; charset=UTF-8

On Monday, August 29, 2016 at 11:22:42 AM UTC-4, Nicolas Capens wrote:
>
> On Wed, Aug 24, 2016 at 6:05 PM, Nicol Bolas <jmck...@gmail.com 
> <javascript:>> wrote:
>
>> On Wednesday, August 24, 2016 at 5:17:26 PM UTC-4, nicolas...@gmail.com 
>> wrote:
>>>
>>> On Wednesday, August 24, 2016 at 3:19:24 PM UTC-4, Matt Calabrese wrote:
>>>>
>>>> On Wed, Aug 24, 2016 at 11:51 AM, <nicolas...@gmail.com> wrote:
>>>>
>>>>> Hi all,
>>>>>
>>>>> 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.
>>>>>
>>>>> The use of this would be to free resources held by the object sooner. 
>>>>> This could be heap memory, file handles, mutex locks, etc. Releasing them 
>>>>> as soon as we're done with the object that represents them would result in 
>>>>> more efficient programs.
>>>>>
>>>>> Currently such optimization can only be achieved by explicitly 
>>>>> releasing the resources, which is inconvenient, bug prone, and reduces 
>>>>> readability. Limiting the scope with extra braces or by putting the 
>>>>> operations in a subroutine also often isn't a desirable workaround. Note 
>>>>> that compilers have been doing liveness analysis for register allocation 
>>>>> and stack compaction for a very long time and we take these optimizations 
>>>>> for granted. I'd like to see it get extended to heap memory and other 
>>>>> resources as well.
>>>>>
>>>>> 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();".
>>>>>
>>>>> Thoughts?
>>>>>
>>>>
>>>> While I would like C++ to eventually get a way to do the equivalent of 
>>>> this in some form (more generally, I want destructive move, which is 
>>>> related to this even though it may not be immediately obvious),
>>>>
>>>
>>> Yes, a destructive assignment could count as a last use of its previous 
>>> value and call the destructor that I'm proposing. I'd also like it to be 
>>> called after the last use as a source argument too though.
>>>  
>>>
>>>> I do not think that the appropriate place to notate the premature 
>>>> destruction is on the destructor declaration. Instead, I believe it needs 
>>>> to be explicit at the usage-site. This is primarily because we are in a 
>>>> language where side-effects matter.
>>>>
>>>
>>> I wouldn't call it premature destruction. Eager instead of today's lazy 
>>> destruction at the end of the scope, seems like a better description to me.
>>>
>>
>> Playing word games doesn't change the fact that the standard makes it 
>> clear that destruction of an automatic object happens in a single, 
>> well-defined place. Your proposal wants to *transparently* change that 
>> location based on something in the type of that object.
>>
>
> It's not a word game. Premature anything is a bad thing and we shouldn't 
> present this feature to users that way. Lazy vs. eager is more neutral. 
> Other suggestions welcome.
>

The term "playing word games" refers to making an argument about the name 
of something in order to make it seem more palatable. So you seem to be 
admitting to playing word games while simultaneously denying it.

You can explicitly reset smart pointers; you can explicitly close streams. 
>> And for moveable types that don't offer such features, Magnus gave a great 
>> answer:
>>
>> Object(std::move(auto_val));
>>
>> That works for pretty much any moveable `Object` type that represents a 
>> resource.
>>
>> The point in time when an automatic variable is destroyed should not be a 
>> *mystery*. It should never be in question when an automatic variable is 
>> no longer a legitimate object.
>>
>
> Why? We don't question whether a register is still in use or not, don't we?
>

I don't know why you keep bringing up registers. Object lifetimes *are not 
like registers* in any way, shape, or form. Registers are an *implementation 
detail* of a particular machine/compiler. Object lifetimes are specified by 
the standard.

This is a false analogy; please stop using it.

So I want to make it clear to the compiler that I'd like it to be destroyed 
>>> eagerly, and not just for this one but for every instance. It's a property 
>>> of the class itself that I want it's destructor to be called eagerly. If I 
>>> don't want that behavior I can simply use an equivalent class without eager 
>>> destructor.
>>>
>>
>> You've provided a very good reason not to do this at all. We do not want 
>> to encourage the proliferation of types that differ *only* by the 
>> presence or absence of "eager destruction". We don't want 
>> `eager_unique_ptr` or `eager_ifstream` or `eager_vector` or whatever.
>>
>
> The way I envision this to be used you won't need such a prefix at all. It 
> would just be Matrix, Int, or Streamer, like in my examples 
> <https://groups.google.com/a/isocpp.org/forum/#!msg/std-proposals/IUxA4cx8yHc/yKNqKl8hDgAJ>. 
> The framework they're part of is responsible of making sure they're 
> self-contained objects and under normal circumstances can't be used 
> incorrectly.
>

Your interface cannot stop people from using the object "incorrectly". 
Consider the template example I used elsewhere:

T t = ...
auto tpl = forward_as_tuple(t);
//do something with tpl.

This is perfectly valid and reasonable code; there is no reason to consider 
this code to not be "under normal circumstances" for C++. Template code 
like this already exists, and it will work with any type `T` which can be 
constructed.

There is nothing you as the creator of the type `T` to make it so that 
`T`'s interface will *prevent* someone from doing this.

And there are no tricks the compiler can play to be absolutely certain that 
`tpl` doesn't contain a reference to `t`. Yes, as I admitted elsewhere, 
`forward_as_tuple` is inline, so the compiler could in theory figure it out 
in that case. But it cannot do so in the *general* case. To the compiler, a 
non-inline function is a complete black box; it knows the inputs and it 
knows the outputs. But it doesn't know what happens in the middle.

This problem is fundamentally identical to the temporary lifetime extension 
problem. Namely, that this works:

const auto &str = std::string(...);
//use str

While this does not:

const auto &str = std::string(...).c_str();
//use str

Why doesn't this work? Because the compiler *cannot know* that `c_str` 
returns a pointer/reference into something controlled by the temporary. 
Therefore, the compiler must assume that the function's return value is 
independent of the lifetime of the parameter/this. This could have worked 
if `c_str` were a data member. But because it's a member function, it will 
not extend the lifetime of the temporary.

Your problem is the exact same thing, just for named variables instead of 
temporaries. The compiler does not and *cannot* know, in all cases, whether 
a return value of a function contains a pointer/reference to an argument or 
an element of an argument.

Your framework cannot prevent "incorrect" use of the type. So your proposal 
is flawed.

-- 
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/85dfd0dc-bf1a-4fa8-81f5-2b36e8f6465c%40isocpp.org.

------=_Part_704_1123617417.1472496396997
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Monday, August 29, 2016 at 11:22:42 AM 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><div class=3D"gmail_quote">On Wed, Aug 24, 2016 at 6:05 PM, Nicol Bolas=
 <span dir=3D"ltr">&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfusc=
ated-mailto=3D"MkuhA1TMEQAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#=
39;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#=
39;;return true;">jmck...@gmail.com</a>&gt;</span> wrote:<br><blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;p=
adding-left:1ex"><div dir=3D"ltr"><span>On Wednesday, August 24, 2016 at 5:=
17:26 PM UTC-4, <a>nicolas...@gmail.com</a> wrote:<blockquote class=3D"gmai=
l_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pad=
ding-left:1ex"><div dir=3D"ltr">On Wednesday, August 24, 2016 at 3:19:24 PM=
 UTC-4, Matt Calabrese wrote:<blockquote class=3D"gmail_quote" style=3D"mar=
gin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div d=
ir=3D"ltr"><div><div class=3D"gmail_quote">On Wed, Aug 24, 2016 at 11:51 AM=
,  <span dir=3D"ltr">&lt;<a rel=3D"nofollow">nicolas...@gmail.com</a>&gt;</=
span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8e=
x;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Hi all=
,</div><div><br></div>I&#39;d like to propose a new kind of destructor that=
 gets called after a local object&#39;s last use, instead of at the end of =
its scope.<div><br></div><div>The use of this would be to free resources he=
ld by the object sooner. This could be heap memory, file handles, mutex loc=
ks, etc. Releasing them as soon as we&#39;re done with the object that repr=
esents them would result in more efficient programs.</div><div><br></div><d=
iv>Currently such optimization can only be achieved by explicitly releasing=
 the resources, which is inconvenient, bug prone, and reduces readability. =
Limiting the scope with extra braces or by putting the operations in a subr=
outine also often isn&#39;t a desirable workaround. Note that compilers hav=
e been doing liveness analysis for register allocation and stack compaction=
 for a very long time and we take these optimizations for granted. I&#39;d =
like to see it get extended to heap memory and other resources as well.</di=
v><div><span style=3D"line-height:17px"><br></span></div><div>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><span style=3D"=
line-height:17px"><br></span></div><div><span style=3D"line-height:17px">Th=
oughts?</span></div></div></blockquote><div><br></div><div>While I would li=
ke C++ to eventually get a way to do the equivalent of this in some form (m=
ore generally, I want destructive move, which is related to this even thoug=
h it may not be immediately obvious),</div></div></div></div></blockquote><=
div><br></div><div>Yes, a destructive assignment could count as a last use =
of its previous value and call the destructor that I&#39;m proposing. I&#39=
;d also like it to be called after the last use as a source argument too th=
ough.</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"><div di=
r=3D"ltr"><div><div class=3D"gmail_quote"><div>I do not think that the appr=
opriate place to notate the premature destruction is on the destructor decl=
aration. Instead, I believe it needs to be explicit at the usage-site. This=
 is primarily because we are in a language where side-effects matter.</div>=
</div></div></div></blockquote><div><br></div><div>I wouldn&#39;t call it p=
remature destruction. Eager instead of today&#39;s lazy destruction at the =
end of the scope, seems like a better description to me.</div></div></block=
quote></span><div><br>Playing word games doesn&#39;t change the fact that t=
he standard makes it clear that destruction of an automatic object happens =
in a single, well-defined place. Your proposal wants to *transparently* cha=
nge that location based on something in the type of that object.<br></div><=
/div></blockquote><div><br></div></div></div><div dir=3D"ltr"><div><div cla=
ss=3D"gmail_quote"><div>It&#39;s not a word game. Premature anything is a b=
ad thing and we shouldn&#39;t present this feature to users that way. Lazy =
vs. eager is more neutral. Other suggestions welcome.</div></div></div></di=
v></div></blockquote><div><br>The term &quot;playing word games&quot; refer=
s to making an argument about the name of something in order to make it see=
m more palatable. So you seem to be admitting to playing word games while s=
imultaneously denying it.<br><br></div><blockquote class=3D"gmail_quote" st=
yle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-lef=
t: 1ex;"><div dir=3D"ltr"><div dir=3D"ltr"><div><div class=3D"gmail_quote">=
<div></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>You can exp=
licitly reset smart pointers; you can explicitly close streams. And for mov=
eable types that don&#39;t offer such features, Magnus gave a great answer:=
<br><br><div style=3D"background-color:rgb(250,250,250);border-color:rgb(18=
7,187,187);border-style:solid;border-width:1px;word-wrap:break-word"><code>=
<div><span style=3D"color:#606">Object</span><span style=3D"color:#660">(</=
span><span style=3D"color:#000">std</span><span style=3D"color:#660">::</sp=
an><span style=3D"color:#000">move</span><span style=3D"color:#660">(</span=
><span style=3D"color:#000">auto_val</span><span style=3D"color:#660">));</=
span></div></code></div><br>That works for pretty much any moveable `Object=
` type that represents a resource.<br><br>The point in time when an automat=
ic variable is destroyed should not be a <i>mystery</i>. It should never be=
 in question when an automatic variable is no longer a legitimate object.<b=
r></div></div></blockquote><div><br></div><div>Why? We don&#39;t question w=
hether a register is still in use or not, don&#39;t we?</div></div></div></=
div></div></blockquote><div><br>I don&#39;t know why you keep bringing up r=
egisters. Object lifetimes <i>are not like registers</i> in any way, shape,=
 or form. Registers are an <i>implementation detail</i> of a particular mac=
hine/compiler. Object lifetimes are specified by the standard.<br><br>This =
is a false analogy; please stop using it.<br><br></div><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 class=
=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div=
><span><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8e=
x;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>So I w=
ant to make it clear to the compiler that I&#39;d like it to be destroyed e=
agerly, and not just for this one but for every instance. It&#39;s a proper=
ty of the class itself that I want it&#39;s destructor to be called eagerly=
.. If I don&#39;t want that behavior I can simply use an equivalent class wi=
thout eager destructor.</div></div></blockquote></span><div><br>You&#39;ve =
provided a very good reason not to do this at all. We do not want to encour=
age the proliferation of types that differ <i>only</i> by the presence or a=
bsence of &quot;eager destruction&quot;. We don&#39;t want `eager_unique_pt=
r` or `eager_ifstream` or `eager_vector` or whatever.<br></div></div></bloc=
kquote><div><br></div><div>The way I envision this to be used you won&#39;t=
 need such a prefix at all. It would just be Matrix, Int, or Streamer, like=
 in <a href=3D"https://groups.google.com/a/isocpp.org/forum/#!msg/std-propo=
sals/IUxA4cx8yHc/yKNqKl8hDgAJ" target=3D"_blank" rel=3D"nofollow" onmousedo=
wn=3D"this.href=3D&#39;https://groups.google.com/a/isocpp.org/forum/#!msg/s=
td-proposals/IUxA4cx8yHc/yKNqKl8hDgAJ&#39;;return true;" onclick=3D"this.hr=
ef=3D&#39;https://groups.google.com/a/isocpp.org/forum/#!msg/std-proposals/=
IUxA4cx8yHc/yKNqKl8hDgAJ&#39;;return true;">my examples</a>. The framework =
they&#39;re part of is responsible of making sure they&#39;re self-containe=
d objects and under normal circumstances can&#39;t be used incorrectly.</di=
v></div></div></div></div></blockquote><div><br>Your interface cannot stop =
people from using the object &quot;incorrectly&quot;. Consider the template=
 example I used elsewhere:<br><br><div class=3D"prettyprint" style=3D"backg=
round-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-s=
tyle: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"pret=
typrint"><div class=3D"subprettyprint"><span style=3D"color: #000;" class=
=3D"styled-by-prettify">T t </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span 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"color: #008;" class=3D"styled-by-prettify">auto</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> tpl </span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> forward_as_tuple</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">t</span><span 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"color: #800;" class=
=3D"styled-by-prettify">//do something with tpl.</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br></span></div></code></div><br>Thi=
s is perfectly valid and reasonable code; there is no reason to consider th=
is code to not be &quot;under normal circumstances&quot; for C++. Template =
code like this already exists, and it will work with any type `T` which can=
 be constructed.<br><br>There is nothing you as the creator of the type `T`=
 to make it so that `T`&#39;s interface will <i>prevent</i> someone from do=
ing this.<br><br>And there are no tricks the compiler can play to be absolu=
tely certain that `tpl` doesn&#39;t contain a reference to `t`. Yes, as I a=
dmitted elsewhere, `forward_as_tuple` is inline, so the compiler could in t=
heory figure it out in that case. But it cannot do so in the <i>general</i>=
 case. To the compiler, a non-inline function is a complete black box; it k=
nows the inputs and it knows the outputs. But it doesn&#39;t know what happ=
ens in the middle.<br><br>This problem is fundamentally identical to the te=
mporary lifetime extension problem. Namely, that this works:<br><br><div cl=
ass=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); border-c=
olor: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap=
: break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">const</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">&amp;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">str </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> std</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">::</span><span style=3D"color: #008;" class=3D"styled-by-prettify">str=
ing</span><span 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"color: #800;" class=3D"styled-by-prettify">//use str</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span></div><=
/code></div><br>While this does not:<br><br><div class=3D"prettyprint" 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 cla=
ss=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008=
;" class=3D"styled-by-prettify">const</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">&amp;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">st=
r </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> std</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">string</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">(...).</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">c_str</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">();</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br></span><span style=3D"color: #800;" class=3D=
"styled-by-prettify">//use str</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br></span></div></code></div><br>Why doesn&#39;t this =
work? Because the compiler <i>cannot know</i> that `c_str` returns a pointe=
r/reference into something controlled by the temporary. Therefore, the comp=
iler must assume that the function&#39;s return value is independent of the=
 lifetime of the parameter/this. This could have worked if `c_str` were a d=
ata member. But because it&#39;s a member function, it will not extend the =
lifetime of the temporary.<br><br>Your problem is the exact same thing, jus=
t for named variables instead of temporaries. The compiler does not and <i>=
cannot</i> know, in all cases, whether a return value of a function contain=
s a pointer/reference to an argument or an element of an argument.<br><br>Y=
our framework cannot prevent &quot;incorrect&quot; use of the type. So your=
 proposal is flawed.<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/85dfd0dc-bf1a-4fa8-81f5-2b36e8f6465c%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/85dfd0dc-bf1a-4fa8-81f5-2b36e8f6465c=
%40isocpp.org</a>.<br />

------=_Part_704_1123617417.1472496396997--

------=_Part_703_2069452979.1472496396996--

.
