Topic: Specifier to cause the destructor to be called at
Author: nicolas.capens@gmail.com
Date: Wed, 24 Aug 2016 11:51:01 -0700 (PDT)
Raw View
------=_Part_2329_2100391000.1472064661001
Content-Type: multipart/alternative;
boundary="----=_Part_2330_1091396675.1472064661001"
------=_Part_2330_1091396675.1472064661001
Content-Type: text/plain; charset=UTF-8
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?
- Nicolas
--
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/ec2e95cc-3ef0-435b-aaf9-13e982c4583e%40isocpp.org.
------=_Part_2330_1091396675.1472064661001
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>Hi all,</div><div><br></div>I'd like to propose a=
new kind of destructor that gets called after a local object's last us=
e, instead of at the end of its scope.<div><br></div><div>The use of this w=
ould be to free resources held by the object sooner. This could be heap mem=
ory, file handles, mutex locks, etc. Releasing them as soon as we're do=
ne with the object that represents them would result in more efficient prog=
rams.</div><div><br></div><div>Currently such optimization can only be achi=
eved by explicitly releasing the resources, which is inconvenient, bug pron=
e, and reduces readability. Limiting the scope with extra braces or by putt=
ing the operations in a subroutine also often isn't a desirable workaro=
und. Note that compilers have been doing liveness analysis for register all=
ocation and stack compaction for a very long time and we take these optimiz=
ations for granted. I'd like to see it get extended to heap memory and =
other resources as well.</div><div><span style=3D"line-height: 17px;"><br><=
/span></div><div>The s<span style=3D"line-height: 17px;">yntax for this cou=
ld be an annotation of the destructor declaration with a keyword, symbol, o=
r attribute. For example, "auto ~Object();", "volatile ~Obje=
ct();", "~~Object();", or "[[eager]] ~Object();".<=
/span></div><div><span style=3D"line-height: 17px;"><br></span></div><div><=
span style=3D"line-height: 17px;">Thoughts?</span></div><div><span style=3D=
"line-height: 17px;">- Nicolas</span></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/ec2e95cc-3ef0-435b-aaf9-13e982c4583e%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/ec2e95cc-3ef0-435b-aaf9-13e982c4583e=
%40isocpp.org</a>.<br />
------=_Part_2330_1091396675.1472064661001--
------=_Part_2329_2100391000.1472064661001--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Wed, 24 Aug 2016 22:01:31 +0300
Raw View
On 24 August 2016 at 21:51, <nicolas.capens@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.
Define "last use".
> 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
...because..?
--
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/CAFk2RUYr21ijENo%2Bw5ooBhuu-kW2V%2BN%2BoqHyzpbO9AM5y-JfPg%40mail.gmail.com.
.
Author: Pablo Oliva <pabloliva87@gmail.com>
Date: Wed, 24 Aug 2016 16:10:02 -0300
Raw View
--001a113eed10416e20053ad60711
Content-Type: text/plain; charset=UTF-8
I don't quite get why simply calling the normal destructor for the object
wouldn't achieve the optimization goals you pretend.
What you seem to be suggesting is that we can signal the complier that an
object should be destroyed as soon as possible. This seems to be more of a
quality of implementation issue on the compiler's side than something that
needs to be standardized. And it doesn't need a different destructor.
Consider asking your compiler vendor for this as an enhancement, or
consider implementing it yourself in an open source compiler. There just
doesn't seem to be anything in this (interesting) idea that should be taken
care of by the standard's committee, unless I have misunderstood it.
2016-08-24 15:51 GMT-03:00 <nicolas.capens@gmail.com>:
> 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?
> - Nicolas
>
> --
> 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/ec2e95cc-3ef0-435b-
> aaf9-13e982c4583e%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/ec2e95cc-3ef0-435b-aaf9-13e982c4583e%40isocpp.org?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/CAPzzLY%3DxcAv2DCwmqZHwv5hkbFsdXOEGUsNdw7G83J%3Djn3m2TQ%40mail.gmail.com.
--001a113eed10416e20053ad60711
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">I don't quite get why simply calling the normal destru=
ctor for the object wouldn't achieve the optimization goals you pretend=
..<div><br></div><div>What you seem to be suggesting is that we can signal t=
he complier that an object should be destroyed as soon as possible. This se=
ems to be more of a quality of implementation issue on the compiler's s=
ide than something that needs to be standardized. And it doesn't need a=
different destructor.</div><div><br></div><div>Consider asking your compil=
er vendor for this as an enhancement, or consider implementing it yourself =
in an open source compiler. There just doesn't seem to be anything in t=
his (interesting) idea that should be taken care of by the standard's c=
ommittee, unless I have misunderstood it.</div></div><div class=3D"gmail_ex=
tra"><br><div class=3D"gmail_quote">2016-08-24 15:51 GMT-03:00 <span dir=
=3D"ltr"><<a href=3D"mailto:nicolas.capens@gmail.com" target=3D"_blank">=
nicolas.capens@gmail.com</a>></span>:<br><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"><div>Hi all,</div><div><br></div>I'd like to propose a=
new kind of destructor that gets called after a local object's last us=
e, instead of at the end of its scope.<div><br></div><div>The use of this w=
ould be to free resources held by the object sooner. This could be heap mem=
ory, file handles, mutex locks, etc. Releasing them as soon as we're do=
ne with the object that represents them would result in more efficient prog=
rams.</div><div><br></div><div>Currently such optimization can only be achi=
eved by explicitly releasing the resources, which is inconvenient, bug pron=
e, and reduces readability. Limiting the scope with extra braces or by putt=
ing the operations in a subroutine also often isn't a desirable workaro=
und. Note that compilers have been doing liveness analysis for register all=
ocation and stack compaction for a very long time and we take these optimiz=
ations for granted. I'd like to see it get extended to heap memory and =
other resources as well.</div><div><span style=3D"line-height:17px"><br></s=
pan></div><div>The s<span style=3D"line-height:17px">yntax for this could b=
e an annotation of the destructor declaration with a keyword, symbol, or at=
tribute. For example, "auto ~Object();", "volatile ~Object()=
;", "~~Object();", or "[[eager]] ~Object();".</spa=
n></div><div><span style=3D"line-height:17px"><br></span></div><div><span s=
tyle=3D"line-height:17px">Thoughts?</span></div><div><span style=3D"line-he=
ight:17px">- Nicolas</span></div></div><span class=3D"HOEnZb"><font color=
=3D"#888888">
<p></p>
-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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" target=3D"_=
blank">std-proposals+unsubscribe@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">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/ec2e95cc-3ef0-435b-aaf9-13e982c4583e%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/ec2e=
95cc-3ef0-435b-<wbr>aaf9-13e982c4583e%40isocpp.org</a><wbr>.<br>
</font></span></blockquote></div><br></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/CAPzzLY%3DxcAv2DCwmqZHwv5hkbFsdXOEGUs=
Ndw7G83J%3Djn3m2TQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAPzzLY%3DxcA=
v2DCwmqZHwv5hkbFsdXOEGUsNdw7G83J%3Djn3m2TQ%40mail.gmail.com</a>.<br />
--001a113eed10416e20053ad60711--
.
Author: =?UTF-8?Q?=27Bernd_L=C3=B6rwald=27_via_ISO_C=2B=2B_Standard_=2D_Future_Proposal?=
Date: Wed, 24 Aug 2016 21:16:47 +0200
Raw View
> Am 24.08.2016 um 21:01 schrieb Ville Voutilainen <ville.voutilainen@gmail=
..com>:
>=20
>> 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
>=20
> ..because..?
It might sometimes be difficult to express the lifetimes as short as possib=
le:
resource a; // begin minimum lifetime a
resource b; // begin minimum lifetime b
last_use (a); // end minimum lifetime a
long_task (b);
last_use (b); //end minimum lifetime b
// end current lifetime b
// end current lifetime a
=20
The explicit braces would require pain:
auto&& b {[&]{
resource a; // begin minimum lifetime a
resource b; // begin minimum lifetime b
lase_use (a); // end minimum lifetime a
return b;
// end current lifetime a
}()};
long_task (b);
last_use (b); //end minimum lifetime b
// end current lifetime b
You really don=E2=80=99t want to write that for more than one variable, do =
you?
--=20
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 e=
mail 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/466EEE26-C7BA-4CD7-A8A5-B86EB179D8F3%40googlemai=
l.com.
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 24 Aug 2016 12:17:46 -0700 (PDT)
Raw View
------=_Part_73_941638373.1472066266965
Content-Type: multipart/alternative;
boundary="----=_Part_74_110875447.1472066266965"
------=_Part_74_110875447.1472066266965
Content-Type: text/plain; charset=UTF-8
On Wednesday, August 24, 2016 at 3:10:04 PM UTC-4, Pablo Oliva wrote:
>
> I don't quite get why simply calling the normal destructor for the object
> wouldn't achieve the optimization goals you pretend.
>
Because that would provoke UB. If you explicitly call the destructor for an
automatic object, the system will still call the destructor at the end of
scope. Unless you reconstructed the object in that memory beforehand, you
will get UB.
What you seem to be suggesting is that we can signal the complier that an
> object should be destroyed as soon as possible. This seems to be more of a
> quality of implementation issue on the compiler's side than something that
> needs to be standardized. And it doesn't need a different destructor.
>
The destructor for a non-trivially destructible automatic object is called
at the end of scope, and will be called in the reverse order of
construction. As such, the side-effects *cannot* happen before the end of
scope. So there's no QOI here; the standard does not permit a non-trivially
destructible automatic object to be destroyed before the end of scope or
out-of-order.
--
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/5c7c5507-698d-460c-bed2-88adb07ebc07%40isocpp.org.
------=_Part_74_110875447.1472066266965
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Wednesday, August 24, 2016 at 3:10:04 PM UTC-4, Pablo O=
liva 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">I =
don't quite get why simply calling the normal destructor for the object=
wouldn't achieve the optimization goals you pretend.</div></blockquote=
><div><br>Because that would provoke UB. If you explicitly call the destruc=
tor for an automatic object, the system will still call the destructor at t=
he end of scope. Unless you reconstructed the object in that memory beforeh=
and, you will get UB.<br><br></div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div dir=3D"ltr"><div></div><div>What you seem to be suggesting is th=
at we can signal the complier that an object should be destroyed as soon as=
possible. This seems to be more of a quality of implementation issue on th=
e compiler's side than something that needs to be standardized. And it =
doesn't need a different destructor.</div></div></blockquote><div><br>T=
he destructor for a non-trivially destructible automatic object is called a=
t the end of scope, and will be called in the reverse order of construction=
.. As such, the side-effects <i>cannot</i> happen before the end of scope. S=
o there's no QOI here; the standard does not permit a non-trivially des=
tructible automatic object to be destroyed before the end of scope or out-o=
f-order. <br></div><br></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/5c7c5507-698d-460c-bed2-88adb07ebc07%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/5c7c5507-698d-460c-bed2-88adb07ebc07=
%40isocpp.org</a>.<br />
------=_Part_74_110875447.1472066266965--
------=_Part_73_941638373.1472066266965--
.
Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Wed, 24 Aug 2016 12:19:20 -0700
Raw View
--001a114e3f328c38a1053ad628d5
Content-Type: text/plain; charset=UTF-8
On Wed, Aug 24, 2016 at 11:51 AM, <nicolas.capens@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), 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.
For example, consider one of the kinds of types that you explicitly called
out: locks. A lock declaration has no actual knowledge of the memory that
it is effectively guarding, so there is no way to *actually* know when the
object is truly done with. Indeed, often times the object isn't even
touched directly *at all* once constructed. Prematurely destroying such an
object would be horrible. This issue is true of basically any object that
has a relationship with another object, such as iterators and their
associated container.
Even with that, you might think that it's okay to annotate types that
contain no logical relationships to objects that it does not own. For
instance, something that just contains an int or a unique_ptr to some
object with no relationships, etc. The problem is, even in these cases,
there is nothing stopping some *other* object from storing a pointer or
reference to an instance of your
automatically-prematurely-destructible-type. If someone *does* hold such a
reference and your annotated type is "no longer used", then the object that
refers to it will now have a dangling reference. Point being, your
annotation cannot be at the type level.
What I'm saying is that while the notion you describe is useful, it
effectively always needs to be explicit in some form at the point of
desired destruction in a language that has pointers and references, like
C++. What you'd do is, when the *user* is done with the object, they'd
notify the compiler -- this would happen somewhat automatically with
something like an explicit destructive move operation if we had them, but
the idea is more general than move operations. Once such a destructive
operation is used, the compiler would diagnose any in-scope uses after that
point, and it would no longer run the destructor at the end of scope.
Further considerations need to be there as well, such as the fact that if
your annotated destructive operation occurs in a nested branch, all other
branches must also have such destructive operations, etc.
--
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/CANh8DEm-3RG1u99c6dUqSgthiVR_wE6FOfzHGbKuMqZBDptcOg%40mail.gmail.com.
--001a114e3f328c38a1053ad628d5
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On W=
ed, Aug 24, 2016 at 11:51 AM, <span dir=3D"ltr"><<a href=3D"mailto:nico=
las.capens@gmail.com" target=3D"_blank">nicolas.capens@gmail.com</a>></s=
pan> wrote:<br><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>Hi all,=
</div><div><br></div>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 i=
ts scope.<div><br></div><div>The use of this would be to free resources hel=
d by the object sooner. This could be heap memory, file handles, mutex lock=
s, etc. Releasing them as soon as we're done with the object that repre=
sents them would result in more efficient programs.</div><div><br></div><di=
v>Currently such optimization can only be achieved by explicitly releasing =
the resources, which is inconvenient, bug prone, and reduces readability. L=
imiting the scope with extra braces or by putting the operations in a subro=
utine 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 l=
ike to see it get extended to heap memory and other resources as well.</div=
><div><span style=3D"line-height:17px"><br></span></div><div>The s<span sty=
le=3D"line-height:17px">yntax for this could be an annotation of the destru=
ctor declaration with a keyword, symbol, or attribute. For example, "a=
uto ~Object();", "volatile ~Object();", "~~Object();&qu=
ot;, or "[[eager]] ~Object();".</span></div><div><span style=3D"l=
ine-height:17px"><br></span></div><div><span style=3D"line-height:17px">Tho=
ughts?</span></div></div></blockquote><div><br></div><div>While I would lik=
e C++ to eventually get a way to do the equivalent of this in some form (mo=
re generally, I want destructive move, which is related to this even though=
it may not be immediately obvious), I do not think that the appropriate pl=
ace to notate the premature destruction is on the destructor declaration. I=
nstead, I believe it needs to be explicit at the usage-site. This is primar=
ily because we are in a language where side-effects matter.</div><div><br><=
/div><div>For example, consider one of the kinds of types that you explicit=
ly called out: locks. A lock declaration has no actual knowledge of the mem=
ory that it is effectively guarding, so there is no way to *actually* know =
when the object is truly done with. Indeed, often times the object isn'=
t even touched directly *at all* once constructed. Prematurely destroying s=
uch an object would be horrible. This issue is true of basically any object=
that has a relationship with another object, such as iterators and their a=
ssociated container.</div><div><br></div><div>Even with that, you might thi=
nk that it's okay to annotate types that contain no logical relationshi=
ps to objects that it does not own. For instance, something that just conta=
ins an int or a unique_ptr to some object with no relationships, etc. The p=
roblem is, even in these cases, there is nothing stopping some *other* obje=
ct from storing a pointer or reference to an instance of your automatically=
-prematurely-destructible-type. If someone *does* hold such a reference and=
your annotated type is "no longer used", then the object that re=
fers to it will now have a dangling reference. Point being, your annotation=
cannot be at the type level.</div><div><br></div><div>What I'm saying =
is that while the notion you describe is useful, it effectively always need=
s to be explicit in some form at the point of desired destruction in a lang=
uage that has pointers and references,=C2=A0like C++. What you'd do is,=
when the *user* is done with the object, they'd notify the compiler --=
this would happen somewhat automatically with something like an explicit d=
estructive move operation if we had them, but the idea is more general than=
move operations. Once such a destructive operation is used, the compiler w=
ould diagnose any in-scope uses after that point, and it would no longer ru=
n the destructor at the end of scope. Further considerations need to be the=
re as well, such as the fact that if your annotated destructive operation o=
ccurs in a nested branch, all other branches must also have such destructiv=
e operations, etc.</div></div></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/CANh8DEm-3RG1u99c6dUqSgthiVR_wE6FOfzH=
GbKuMqZBDptcOg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANh8DEm-3RG1u99c=
6dUqSgthiVR_wE6FOfzHGbKuMqZBDptcOg%40mail.gmail.com</a>.<br />
--001a114e3f328c38a1053ad628d5--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 24 Aug 2016 12:21:23 -0700 (PDT)
Raw View
------=_Part_660_328973787.1472066483544
Content-Type: multipart/alternative;
boundary="----=_Part_661_69617179.1472066483544"
------=_Part_661_69617179.1472066483544
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Wednesday, August 24, 2016 at 3:16:52 PM UTC-4, Bernd L=C3=B6rwald wrote=
:
>
>
> > Am 24.08.2016 um 21:01 schrieb Ville Voutilainen <ville.vo...@gmail.com=
=20
> <javascript:>>:=20
> >=20
> >> Limiting the scope with extra braces or by putting the operations in a=
=20
> >> subroutine also often isn't a desirable workaround. Note that compiler=
s=20
> have=20
> >=20
> > ..because..?=20
>
> It might sometimes be difficult to express the lifetimes as short as=20
> possible:=20
>
> resource a; // begin minimum lifetime a=20
> resource b; // begin minimum lifetime b=20
> last_use (a); // end minimum lifetime a=20
> long_task (b);=20
> last_use (b); //end minimum lifetime b=20
> // end current lifetime b=20
> // end current lifetime a=20
> =20
>
And how do you know that `b` isn't using `a`? That's the point of Ville's=
=20
"Define 'last use'." question. You cannot just look at code and know that=
=20
`a` is finished being used when the locally visible code stops using it.
Destruction of automatic objects in the reverse order of their construction=
=20
is a guarantee that the standard should not arbitrarily discard.
--=20
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 e=
mail 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/a54b7cf2-6c83-48d5-aeb6-4c179cef1520%40isocpp.or=
g.
------=_Part_661_69617179.1472066483544
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Wednesday, August 24, 2016 at 3:16:52 PM UTC-4, Bernd L=
=C3=B6rwald wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>> Am 24.08.2016 um 21:01 schrieb Ville Voutilainen <<a href=3D"ja=
vascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"RQb6btHLDQAJ" rel=3D"=
nofollow" onmousedown=3D"this.href=3D'javascript:';return true;" on=
click=3D"this.href=3D'javascript:';return true;">ville.vo...@gmail.=
com</a>>:
<br>>=20
<br>>> Limiting the scope with extra braces or by putting the operati=
ons in a
<br>>> subroutine also often isn't a desirable workaround. Note t=
hat compilers have
<br>>=20
<br>> ..because..?
<br>
<br>It might sometimes be difficult to express the lifetimes as short as po=
ssible:
<br>
<br>=C2=A0 resource a; // begin minimum lifetime a
<br>=C2=A0 resource b; // begin minimum lifetime b
<br>=C2=A0 last_use (a); // end minimum lifetime a
<br>=C2=A0 long_task (b);
<br>=C2=A0 last_use (b); //end minimum lifetime b
<br>=C2=A0 // end current lifetime b
<br>=C2=A0 // end current lifetime a
<br>=C2=A0=20
<br></blockquote><div><br>And how do you know that `b` isn't using `a`?=
That's the point of=20
Ville's "Define 'last use'." question. You cannot jus=
t look at code and=20
know that `a` is finished being used when the locally visible code stops us=
ing it.<br><br>Destruction of automatic objects in the reverse order of the=
ir construction is a guarantee that the standard should not arbitrarily dis=
card.<br></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/a54b7cf2-6c83-48d5-aeb6-4c179cef1520%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/a54b7cf2-6c83-48d5-aeb6-4c179cef1520=
%40isocpp.org</a>.<br />
------=_Part_661_69617179.1472066483544--
------=_Part_660_328973787.1472066483544--
.
Author: =?UTF-8?Q?=27Bernd_L=C3=B6rwald=27_via_ISO_C=2B=2B_Standard_=2D_Future_Proposal?=
Date: Wed, 24 Aug 2016 21:25:55 +0200
Raw View
> And how do you know that `b` isn't using `a`? That's the point of Ville's=
"Define 'last use'." question. You cannot just look at code and know that =
`a` is finished being used when the locally visible code stops using it.
I understand determining =E2=80=9Elast use=E2=80=9C is hard, which is why I=
explicitly wrote =E2=80=9Elast_use()=E2=80=9C and did not let them depend =
on each other in initialization. Detecting =E2=80=9Enow unused until dtor=
=E2=80=9C is of course hard and non-local. It is probably also more likely =
that the compiler would be better at detecting it than most humans are.
> Destruction of automatic objects in the reverse order of their constructi=
on is a guarantee that the standard should not arbitrarily discard.
I am a huge fan of automatic storage and reverse order destruction, which I=
instantly miss in other languages. I was just trying to give an example as=
to why doing it explicitly is not trivial either.=20
--=20
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 e=
mail 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/804ACD7E-871C-4411-8C6D-C87299A9FBA0%40googlemai=
l.com.
.
Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Wed, 24 Aug 2016 12:31:51 -0700
Raw View
--94eb2c1244ca4c10b5053ad65519
Content-Type: text/plain; charset=UTF-8
On Wed, Aug 24, 2016 at 12:19 PM, Matt Calabrese <calabrese@x.team> wrote:
>
> What I'm saying is that while the notion you describe is useful, it
> effectively always needs to be explicit in some form at the point of
> desired destruction in a language that has pointers and references, like
> C++. What you'd do is, when the *user* is done with the object, they'd
> notify the compiler -- this would happen somewhat automatically with
> something like an explicit destructive move operation if we had them, but
> the idea is more general than move operations. Once such a destructive
> operation is used, the compiler would diagnose any in-scope uses after that
> point, and it would no longer run the destructor at the end of scope.
>
Technically it would just be UB, much like functions encountering return
statements, but in practice it, too, would be properly diagnosed in the
vast majority of cases.
--
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/CANh8DEmeZQfLKp%2BcU-2%2B80t3uJT%3DcJ_1A6tc-74o43wSmS4UxQ%40mail.gmail.com.
--94eb2c1244ca4c10b5053ad65519
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On W=
ed, Aug 24, 2016 at 12:19 PM, Matt Calabrese <span dir=3D"ltr"><<a href=
=3D"mailto:calabrese@x.team" target=3D"_blank">calabrese@x.team</a>></sp=
an> wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bord=
er-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gma=
il_extra"><div class=3D"gmail_quote"><div>What I'm saying is that while=
the notion you describe is useful, it effectively always needs to be expli=
cit in some form at the point of desired destruction in a language that has=
pointers and references,=C2=A0like C++. What you'd do is, when the *us=
er* is done with the object, they'd notify the compiler -- this would h=
appen somewhat automatically with something like an explicit destructive mo=
ve operation if we had them, but the idea is more general than move operati=
ons. Once such a destructive operation is used, the compiler would diagnose=
any in-scope uses after that point, and it would no longer run the destruc=
tor at the end of scope.</div></div></div></div>
</blockquote></div><br></div><div class=3D"gmail_extra">Technically it woul=
d just be UB, much like functions encountering return statements, but in pr=
actice it, too, would be properly diagnosed in the vast majority of cases.<=
/div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/CANh8DEmeZQfLKp%2BcU-2%2B80t3uJT%3DcJ=
_1A6tc-74o43wSmS4UxQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANh8DEmeZQ=
fLKp%2BcU-2%2B80t3uJT%3DcJ_1A6tc-74o43wSmS4UxQ%40mail.gmail.com</a>.<br />
--94eb2c1244ca4c10b5053ad65519--
.
Author: Thiago Macieira <thiago@macieira.org>
Date: Wed, 24 Aug 2016 12:52:55 -0700
Raw View
On quarta-feira, 24 de agosto de 2016 11:51:01 PDT nicolas.capens@gmail.com
wrote:
> 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.
Locks are the perfect counter-example to what you're proposing. The compiler
simply cannot tell what the "last use" is:
std::lock_guard lock(mutex);
i = 1;
Where was the last use: before or after the assignment to i?
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
--
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/5044039.aVzB6kA9Ui%40tjmaciei-mobl1.
.
Author: Thiago Macieira <thiago@macieira.org>
Date: Wed, 24 Aug 2016 12:56:15 -0700
Raw View
On quarta-feira, 24 de agosto de 2016 12:19:20 PDT 'Matt Calabrese' via ISO C+
+ Standard - Future Proposals wrote:
> For example, consider one of the kinds of types that you explicitly called
> out: locks. A lock declaration has no actual knowledge of the memory that
> it is effectively guarding, so there is no way to *actually* know when the
> object is truly done with. Indeed, often times the object isn't even
> touched directly *at all* once constructed. Prematurely destroying such an
> object would be horrible. This issue is true of basically any object that
> has a relationship with another object, such as iterators and their
> associated container.
We can go further: files can be locks too, locking something that may not even
be under control of the current process. There's simply nothing to be
annotated.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
--
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/5522941.HtKcEv3XOe%40tjmaciei-mobl1.
.
Author: nicolas.capens@gmail.com
Date: Wed, 24 Aug 2016 13:16:30 -0700 (PDT)
Raw View
------=_Part_94_1878317665.1472069790282
Content-Type: multipart/alternative;
boundary="----=_Part_95_802756773.1472069790282"
------=_Part_95_802756773.1472069790282
Content-Type: text/plain; charset=UTF-8
On Wednesday, August 24, 2016 at 3:01:34 PM UTC-4, Ville Voutilainen wrote:
>
> On 24 August 2016 at 21:51, <nicolas...@gmail.com <javascript:>> 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.
>
> Define "last use".
>
The last use according to liveness analysis.
> > 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
>
> ..because..?
>
The code would become littered with braces if you want to limit the scope
of each object to its miminal range, and it would be annoying to maintain
when refactoring the code. Just imagine having to do it for scalar
variables to avoid register spilling. Fortunately we don't, because today's
compilers do liveness analysis to optimize register allocation. I'd like to
see that extended to the resources managed by objects.
--
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/6aa24874-7bae-449f-ac2b-67f0605fbd65%40isocpp.org.
------=_Part_95_802756773.1472069790282
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Wednesday, August 24, 2016 at 3:01:34 PM UTC-4, Ville V=
outilainen wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 24 August =
2016 at 21:51, =C2=A0<<a href=3D"javascript:" target=3D"_blank" gdf-obfu=
scated-mailto=3D"J6h1r_vKDQAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D=
'javascript:';return true;" onclick=3D"this.href=3D'javascript:=
';return true;">nicolas...@gmail.com</a>> wrote:
<br>> Hi all,
<br>>
<br>> I'd like to propose a new kind of destructor that gets called =
after a local
<br>> object's last use, instead of at the end of its scope.
<br>
<br>Define "last use".
<br></blockquote><div><br></div><div>The last use according to liveness ana=
lysis.</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"mar=
gin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">&=
gt; Limiting the scope with extra braces or by putting the operations in a
<br>> subroutine also often isn't a desirable workaround. Note that =
compilers have
<br>
<br>..because..?
<br></blockquote><div><br></div><div>The code would become littered with br=
aces if you want to limit the scope of each object to its miminal range, an=
d it would be annoying to maintain when refactoring the code. Just imagine =
having to do it for scalar variables to avoid register spilling. Fortunatel=
y we don't, because today's compilers do liveness analysis to optim=
ize register allocation. I'd like to see that extended to the resources=
managed by objects.</div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/6aa24874-7bae-449f-ac2b-67f0605fbd65%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/6aa24874-7bae-449f-ac2b-67f0605fbd65=
%40isocpp.org</a>.<br />
------=_Part_95_802756773.1472069790282--
------=_Part_94_1878317665.1472069790282--
.
Author: Nevin Liber <nevin@eviloverlord.com>
Date: Wed, 24 Aug 2016 15:21:55 -0500
Raw View
--001a113e45aebd195f053ad70abd
Content-Type: text/plain; charset=UTF-8
On 24 August 2016 at 15:16, <nicolas.capens@gmail.com> wrote:
> The code would become littered with braces if you want to limit the scope
> of each object to its miminal range,
>
I don't understand why you would want to do that. Could you elaborate?
And if the objects are truly independent and have no observable effect,
can't a compiler do that under the as-if rule?
Also, if you wish to have a lifetime shorter than a scope for an object of
type T, you can just use std::optional<T>.
> Fortunately we don't, because today's compilers do liveness analysis to
> optimize register allocation.
>
One of the huge benefits to C++ is that destruction happens at well defined
times. This would break that.
--
Nevin ":-)" Liber <mailto:nevin@eviloverlord.com> +1-847-691-1404
--
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/CAGg_6%2BM3M43y_8jTg4mXce1sz7UQ5kzSkOVqL3F_nYEe-ogzNA%40mail.gmail.com.
--001a113e45aebd195f053ad70abd
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On 24 August 2016 at 15:16, <span dir=3D"ltr"><<a href=
=3D"mailto:nicolas.capens@gmail.com" target=3D"_blank">nicolas.capens@gmail=
..com</a>></span> wrote:<br><div class=3D"gmail_extra"><div class=3D"gmai=
l_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;borde=
r-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>The code woul=
d become littered with braces if you want to limit the scope of each object=
to its miminal range,</div></div></blockquote><div><br></div><div>I don=
9;t understand why you would want to do that.=C2=A0 Could you elaborate?</d=
iv><div><br></div><div>And if the objects are truly independent and have no=
observable effect, can't a compiler do that under the as-if rule?</div=
><div><br></div><div>Also, if you wish to have a lifetime shorter than a sc=
ope for an object of type T, you can just use std::optional<T>.</div>=
<div>=C2=A0</div><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>Fortu=
nately we don't, because today's compilers do liveness analysis to =
optimize register allocation.</div></div></blockquote><div><br></div><div>O=
ne of the huge benefits to C++ is that destruction happens at well defined =
times.=C2=A0 This would break that.</div></div>-- <br><div class=3D"gmail_s=
ignature" data-smartmail=3D"gmail_signature"><div dir=3D"ltr"><div><div dir=
=3D"ltr"><div>=C2=A0Nevin ":-)" Liber=C2=A0 <mailto:<a href=3D=
"mailto:nevin@eviloverlord.com" target=3D"_blank">nevin@eviloverlord.com</a=
>> =C2=A0+1-847-691-1404</div></div></div></div></div>
</div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/CAGg_6%2BM3M43y_8jTg4mXce1sz7UQ5kzSkO=
VqL3F_nYEe-ogzNA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAGg_6%2BM3M43y=
_8jTg4mXce1sz7UQ5kzSkOVqL3F_nYEe-ogzNA%40mail.gmail.com</a>.<br />
--001a113e45aebd195f053ad70abd--
.
Author: nicolas.capens@gmail.com
Date: Wed, 24 Aug 2016 13:25:11 -0700 (PDT)
Raw View
------=_Part_0_410596719.1472070311768
Content-Type: multipart/alternative;
boundary="----=_Part_1_479350577.1472070311779"
------=_Part_1_479350577.1472070311779
Content-Type: text/plain; charset=UTF-8
On Wednesday, August 24, 2016 at 3:10:04 PM UTC-4, Pablo Oliva wrote:
>
> I don't quite get why simply calling the normal destructor for the object
> wouldn't achieve the optimization goals you pretend.
>
It does. But like I wrote before, it's inconvenient, bug prone, and reduces
readability. Imagine having to explicitly call a "destructor" on every
scalar variable after its last use to make its register available for
another variable. We take it for granted that we don't have to do this
thanks to liveness analysis. Why accept that we need to do it explicitly
for releasing the resources managed by objects?
> What you seem to be suggesting is that we can signal the complier that an
> object should be destroyed as soon as possible. This seems to be more of a
> quality of implementation issue on the compiler's side than something that
> needs to be standardized. And it doesn't need a different destructor.
>
Compilers aren't at liberty to call the destructor before the end of the
object's scope, unless it has no side effects. So it doesn't work for any
object that manages any resources like heap memory. To allow for it while
also keeping the legacy behavior we need a new type of destructor.
> Consider asking your compiler vendor for this as an enhancement, or
> consider implementing it yourself in an open source compiler. There just
> doesn't seem to be anything in this (interesting) idea that should be taken
> care of by the standard's committee, unless I have misunderstood it.
>
> 2016-08-24 15:51 GMT-03:00 <nicolas...@gmail.com <javascript:>>:
>
>> 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?
>> - Nicolas
>>
>> --
>> 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-proposal...@isocpp.org <javascript:>.
>> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
>> To view this discussion on the web visit
>> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/ec2e95cc-3ef0-435b-aaf9-13e982c4583e%40isocpp.org
>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/ec2e95cc-3ef0-435b-aaf9-13e982c4583e%40isocpp.org?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/ff7eaf2b-d0ce-446d-9ec0-fac31632da29%40isocpp.org.
------=_Part_1_479350577.1472070311779
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Wednesday, August 24, 2016 at 3:10:04 PM UTC-4, Pablo O=
liva 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">I =
don't quite get why simply calling the normal destructor for the object=
wouldn't achieve the optimization goals you pretend.</div></blockquote=
><div><br></div><div>It does. But like I wrote before, it's inconvenien=
t, bug prone, and reduces readability. Imagine having to explicitly call a =
"destructor" on every scalar variable after its last use to make =
its register available for another variable. We take it for granted that we=
don't have to do this thanks to liveness analysis. Why accept that we =
need to do it explicitly for releasing the resources managed by objects?</d=
iv><div>=C2=A0</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>What you seem to be suggesting is that we can signal the comp=
lier that an object should be destroyed as soon as possible. This seems to =
be more of a quality of implementation issue on the compiler's side tha=
n something that needs to be standardized. And it doesn't need a differ=
ent destructor.</div></div></blockquote><div><br></div><div>Compilers aren&=
#39;t at liberty to call the destructor before the end of the object's =
scope, unless it has no side effects. So it doesn't work for any object=
that manages any resources like heap memory. To allow for it while also ke=
eping the legacy behavior we need a new type of destructor.</div><div>=C2=
=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div=
>Consider asking your compiler vendor for this as an enhancement, or consid=
er implementing it yourself in an open source compiler. There just doesn=
9;t seem to be anything in this (interesting) idea that should be taken car=
e of by the standard's committee, unless I have misunderstood it.</div>=
</div><div><br><div class=3D"gmail_quote">2016-08-24 15:51 GMT-03:00 <span=
dir=3D"ltr"><<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-m=
ailto=3D"DOstcHLLDQAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'jav=
ascript:';return true;" onclick=3D"this.href=3D'javascript:';re=
turn true;">nicolas...@gmail.com</a>></span>:<br><blockquote class=3D"gm=
ail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-le=
ft:1ex"><div dir=3D"ltr"><div>Hi all,</div><div><br></div>I'd like to p=
ropose a new kind of destructor that gets called after a local object's=
last use, instead of at the end of its scope.<div><br></div><div>The use o=
f 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&#=
39;re done with the object that represents them would result in more effici=
ent programs.</div><div><br></div><div>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 regi=
ster 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 mem=
ory and other resources as well.</div><div><span style=3D"line-height:17px"=
><br></span></div><div>The s<span style=3D"line-height:17px">yntax for this=
could be an annotation of the destructor declaration with a keyword, symbo=
l, or attribute. For example, "auto ~Object();", "volatile ~=
Object();", "~~Object();", or "[[eager]] ~Object();&quo=
t;.</span></div><div><span style=3D"line-height:17px"><br></span></div><div=
><span style=3D"line-height:17px">Thoughts?</span></div><div><span style=3D=
"line-height:17px">- Nicolas</span></div></div><span><font color=3D"#888888=
">
<p></p>
-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
DOstcHLLDQAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:&=
#39;;return true;" onclick=3D"this.href=3D'javascript:';return true=
;">std-proposal...@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"javascript:" target=3D"_bla=
nk" gdf-obfuscated-mailto=3D"DOstcHLLDQAJ" rel=3D"nofollow" onmousedown=3D"=
this.href=3D'javascript:';return true;" onclick=3D"this.href=3D'=
;javascript:';return true;">std-pr...@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/ec2e95cc-3ef0-435b-aaf9-13e982c4583e%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter" target=3D"_blank" =
rel=3D"nofollow" onmousedown=3D"this.href=3D'https://groups.google.com/=
a/isocpp.org/d/msgid/std-proposals/ec2e95cc-3ef0-435b-aaf9-13e982c4583e%40i=
socpp.org?utm_medium\x3demail\x26utm_source\x3dfooter';return true;" on=
click=3D"this.href=3D'https://groups.google.com/a/isocpp.org/d/msgid/st=
d-proposals/ec2e95cc-3ef0-435b-aaf9-13e982c4583e%40isocpp.org?utm_medium\x3=
demail\x26utm_source\x3dfooter';return true;">https://groups.google.com=
/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/ec2e95cc-3ef0-435b-<wbr>aaf9-=
13e982c4583e%40isocpp.org</a><wbr>.<br>
</font></span></blockquote></div><br></div>
</blockquote></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/ff7eaf2b-d0ce-446d-9ec0-fac31632da29%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/ff7eaf2b-d0ce-446d-9ec0-fac31632da29=
%40isocpp.org</a>.<br />
------=_Part_1_479350577.1472070311779--
------=_Part_0_410596719.1472070311768--
.
Author: nicolas.capens@gmail.com
Date: Wed, 24 Aug 2016 14:17:25 -0700 (PDT)
Raw View
------=_Part_14_934982376.1472073445965
Content-Type: multipart/alternative;
boundary="----=_Part_15_14091566.1472073445970"
------=_Part_15_14091566.1472073445970
Content-Type: text/plain; charset=UTF-8
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 <javascript:>>
> 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.
Anyway, for the use cases that I envision, the annotation at destructor
declaration is appropriate. For example say I need a huge matrix to
temporarily store some intermediate results. I could use "double
matrix[10000][10000];" and rely on the compiler's optimizations to use the
memory for other purposes as soon as I'm done with this matrix. But it's
simply not going to fit on the stack. So instead I'll use an object with a
pointer to heap memory. But now it only gets freed when it goes out of
scope. 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.
> For example, consider one of the kinds of types that you explicitly called
> out: locks. A lock declaration has no actual knowledge of the memory that
> it is effectively guarding, so there is no way to *actually* know when the
> object is truly done with. Indeed, often times the object isn't even
> touched directly *at all* once constructed. Prematurely destroying such an
> object would be horrible. This issue is true of basically any object that
> has a relationship with another object, such as iterators and their
> associated container.
>
The solution here is to make the lock and the memory that it's guarding
part of the same object.
> Even with that, you might think that it's okay to annotate types that
> contain no logical relationships to objects that it does not own. For
> instance, something that just contains an int or a unique_ptr to some
> object with no relationships, etc. The problem is, even in these cases,
> there is nothing stopping some *other* object from storing a pointer or
> reference to an instance of your
> automatically-prematurely-destructible-type. If someone *does* hold such a
> reference and your annotated type is "no longer used", then the object that
> refers to it will now have a dangling reference. Point being, your
> annotation cannot be at the type level.
>
This issue is not very different from still having a reference to a local
variable after it has gone out of scope. C++ is inherently unsafe, and you
simply need to know what you're doing. With lazy destruction, don't use any
references to the object after it has gone out of scope. With eager
destruction, don't use any references to the object after its last use. A
compiler warning could help prevent people from shooting themselves in the
foot in both cases.
> What I'm saying is that while the notion you describe is useful, it
> effectively always needs to be explicit in some form at the point of
> desired destruction in a language that has pointers and references, like
> C++. What you'd do is, when the *user* is done with the object, they'd
> notify the compiler -- this would happen somewhat automatically with
> something like an explicit destructive move operation if we had them, but
> the idea is more general than move operations. Once such a destructive
> operation is used, the compiler would diagnose any in-scope uses after that
> point, and it would no longer run the destructor at the end of scope.
> Further considerations need to be there as well, such as the fact that if
> your annotated destructive operation occurs in a nested branch, all other
> branches must also have such destructive operations, etc.
>
--
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/db0b8dd4-5cd9-4d4d-b7a8-95d6ab15ad8c%40isocpp.org.
------=_Part_15_14091566.1472073445970
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Wednesday, August 24, 2016 at 3:19:24 PM UTC-4,=
Matt Calabrese 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"><div><div class=3D"gmail_quote">On Wed, Aug 24, 2016 at 11:51 AM, =
<span dir=3D"ltr"><<a href=3D"javascript:" target=3D"_blank" gdf-obfusc=
ated-mailto=3D"FxnW0fTLDQAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#=
39;javascript:';return true;" onclick=3D"this.href=3D'javascript:&#=
39;;return true;">nicolas...@gmail.com</a>></span> wrote:<br><blockquote=
class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc soli=
d;padding-left:1ex"><div dir=3D"ltr"><div>Hi all,</div><div><br></div>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.<div><br></div><d=
iv>The use of this would be to free resources held by the object sooner. Th=
is 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.</div><div><br></div><div>Currently such optimizat=
ion can only be achieved by explicitly releasing the resources, which is in=
convenient, bug prone, and reduces readability. Limiting the scope with ext=
ra braces or by putting the operations in a subroutine also often isn't=
a desirable workaround. Note that compilers have been doing liveness analy=
sis for register allocation and stack compaction for a very long time and w=
e take these optimizations for granted. I'd like to see it get extended=
to heap memory and other resources as well.</div><div><span style=3D"line-=
height:17px"><br></span></div><div>The s<span style=3D"line-height:17px">yn=
tax for this could be an annotation of the destructor declaration with a ke=
yword, symbol, or attribute. For example, "auto ~Object();", &quo=
t;volatile ~Object();", "~~Object();", or "[[eager]] ~O=
bject();".</span></div><div><span style=3D"line-height:17px"><br></spa=
n></div><div><span style=3D"line-height:17px">Thoughts?</span></div></div><=
/blockquote><div><br></div><div>While I would like C++ to eventually get a =
way to do the equivalent of this in some form (more generally, I want destr=
uctive move, which is related to this even though it may not be immediately=
obvious),</div></div></div></div></blockquote><div><br></div><div>Yes, a d=
estructive assignment could count as a last use of its previous value and c=
all the destructor that I'm proposing. I'd also like it to be calle=
d after the last use as a source argument too though.</div><div>=C2=A0</div=
><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bo=
rder-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div cl=
ass=3D"gmail_quote"><div>I do not think that the appropriate place to notat=
e the premature destruction is on the destructor declaration. Instead, I be=
lieve 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></bl=
ockquote><div><br></div><div>I wouldn't call it premature destruction. =
Eager instead of today's lazy destruction at the end of the scope, seem=
s like a better description to me.</div><div><br></div><div>Anyway, for the=
use cases that I envision, the annotation at destructor declaration is app=
ropriate. For example say I need a huge matrix to temporarily store some in=
termediate results. I could use "double matrix[10000][10000];" an=
d rely on the compiler's optimizations to use the memory for other purp=
oses as soon as I'm done with this matrix. But it's simply not goin=
g to fit on the stack. So instead I'll use an object with a pointer to =
heap memory. But now it only gets freed when it goes out of scope. So I wan=
t to make it clear to the compiler that I'd like it to be destroyed eag=
erly, 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 with=
out eager destructor.</div><div>=C2=A0</div><blockquote class=3D"gmail_quot=
e" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddin=
g-left: 1ex;"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div>For exa=
mple, consider one of the kinds of types that you explicitly called out: lo=
cks. A lock declaration has no actual knowledge of the memory that it is ef=
fectively guarding, so there is no way to *actually* know when the object i=
s truly done with. Indeed, often times the object isn't even touched di=
rectly *at all* once constructed. Prematurely destroying such an object wou=
ld be horrible. This issue is true of basically any object that has a relat=
ionship with another object, such as iterators and their associated contain=
er.</div></div></div></div></blockquote><div><br></div><div>The solution he=
re is to make the lock and the memory that it's guarding part of the sa=
me object.</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D=
"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex=
;"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div>Even with that, yo=
u might think that it's okay to annotate types that contain no logical =
relationships to objects that it does not own. For instance, something that=
just contains an int or a unique_ptr to some object with no relationships,=
etc. The problem is, even in these cases, there is nothing stopping some *=
other* object from storing a pointer or reference to an instance of your au=
tomatically-prematurely-<wbr>destructible-type. If someone *does* hold such=
a reference and your annotated type is "no longer used", then th=
e object that refers to it will now have a dangling reference. Point being,=
your annotation cannot be at the type level.</div></div></div></div></bloc=
kquote><div><br></div><div>This issue is not very different from still havi=
ng a reference to a local variable after it has gone out of scope. C++ is i=
nherently unsafe, and you simply need to know what you're doing. With l=
azy destruction, don't use any references to the object after it has go=
ne out of scope. With eager destruction, don't use any references to th=
e object after its last use. A compiler warning could help prevent people f=
rom shooting themselves in the foot in both cases.</div><div>=C2=A0</div><b=
lockquote 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><div class=
=3D"gmail_quote"><div>What I'm saying is that while the notion you desc=
ribe is useful, it effectively always needs to be explicit in some form at =
the point of desired destruction in a language that has pointers and refere=
nces,=C2=A0like C++. What you'd do is, when the *user* is done with the=
object, they'd notify the compiler -- this would happen somewhat autom=
atically with something like an explicit destructive move operation if we h=
ad them, but the idea is more general than move operations. Once such a des=
tructive operation is used, the compiler would diagnose any in-scope uses a=
fter that point, and it would no longer run the destructor at the end of sc=
ope. Further considerations need to be there as well, such as the fact that=
if your annotated destructive operation occurs in a nested branch, all oth=
er branches must also have such destructive operations, etc.</div></div></d=
iv></div>
</blockquote></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/db0b8dd4-5cd9-4d4d-b7a8-95d6ab15ad8c%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/db0b8dd4-5cd9-4d4d-b7a8-95d6ab15ad8c=
%40isocpp.org</a>.<br />
------=_Part_15_14091566.1472073445970--
------=_Part_14_934982376.1472073445965--
.
Author: inkwizytoryankes@gmail.com
Date: Wed, 24 Aug 2016 14:31:32 -0700 (PDT)
Raw View
------=_Part_9_1329968008.1472074292873
Content-Type: multipart/alternative;
boundary="----=_Part_10_1690637891.1472074292873"
------=_Part_10_1690637891.1472074292873
Content-Type: text/plain; charset=UTF-8
On Wednesday, August 24, 2016 at 10:16:30 PM UTC+2, nicolas...@gmail.com
wrote:
>
> On Wednesday, August 24, 2016 at 3:01:34 PM UTC-4, Ville Voutilainen wrote:
>>
>> On 24 August 2016 at 21:51, <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.
>>
>> Define "last use".
>>
>
> The last use according to liveness analysis.
>
>
I have 4 functions:
int main()
{
resource a;
funcA(&a);
funcB();
funcC();
funcD();
}
What function `funcA` do with `a`? What if it store reference to `a` for
future use (or reference to any part of it)? What if `funcB` or `funcD` use
this reference too? `a` could be used in other thread (`funcA` ===
`startThread` and `funcD` === `joinThread`).
Compiler can't know that. Even more, this functions could not exists in exe
at all and be from run time dll.
--
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/648af6db-e066-4879-93b2-667fbd8972b7%40isocpp.org.
------=_Part_10_1690637891.1472074292873
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Wednesday, August 24, 2016 at 10:16:30 PM UTC+2=
, nicolas...@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"mar=
gin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><=
div dir=3D"ltr">On Wednesday, August 24, 2016 at 3:01:34 PM UTC-4, Ville Vo=
utilainen wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-=
left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">On 24 August 2016 a=
t 21:51, =C2=A0<<a rel=3D"nofollow">nicolas...@gmail.com</a>> wrote:
<br>> Hi all,
<br>>
<br>> I'd like to propose a new kind of destructor that gets called =
after a local
<br>> object's last use, instead of at the end of its scope.
<br>
<br>Define "last use".
<br></blockquote><div><br></div><div>The last use according to liveness ana=
lysis.</div><div>=C2=A0</div></div></blockquote><div><br>I have 4 functions=
:<br><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 25=
0); border-color: rgb(187, 187, 187); border-style: solid; border-width: 1p=
x; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subpre=
ttyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">int</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> main</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">()</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 resource a</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 funcA</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">(&</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">a</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 funcB</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">();</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 funcC</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">();</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 funcD</spa=
n><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: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br></span></div></code></div>What fu=
nction `funcA` do with `a`? What if it store reference to `a` for future us=
e (or reference to any part of it)? What if `funcB` or `funcD` use this ref=
erence too? `a` could be used in other thread (`funcA` =3D=3D=3D `startThre=
ad` and `funcD` =3D=3D=3D `joinThread`).<br>Compiler can't know that. E=
ven more, this functions could not exists in exe at all and be from run tim=
e dll.<br><br><br></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/648af6db-e066-4879-93b2-667fbd8972b7%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/648af6db-e066-4879-93b2-667fbd8972b7=
%40isocpp.org</a>.<br />
------=_Part_10_1690637891.1472074292873--
------=_Part_9_1329968008.1472074292873--
.
Author: Magnus Fromreide <magfr@lysator.liu.se>
Date: Wed, 24 Aug 2016 23:43:38 +0200
Raw View
On Wed, Aug 24, 2016 at 11:51:01AM -0700, nicolas.capens@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();".
This do sound like you are expecting the normal destructor to get called at
end of scope, is this correct?
If so then what would this extra destructor do that
T(std::move(aT));
doesn't do today?
/MF
--
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/20160824214337.GA18752%40noemi.
.
Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Wed, 24 Aug 2016 15:00:54 -0700
Raw View
--94eb2c1244ca53e691053ad86ae6
Content-Type: text/plain; charset=UTF-8
On Wed, Aug 24, 2016 at 2:17 PM, <nicolas.capens@gmail.com> wrote:
> On Wednesday, August 24, 2016 at 3:19:24 PM UTC-4, Matt Calabrese wrote:
>>
>> 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.
>
Again, the problem is that "last use" isn't something that can actually be
determined in any meaningful sense. For this to be usable, the *user* needs
to notate their last use by explicitly calling some kind of special
destructive operation that doesn't currently exist in the language (a
hypothetical destructive move operation would be one of those special kinds
of operations). I and others have given you examples of why what you want
cannot be done truly automatically in a language like C++.
On Wed, Aug 24, 2016 at 2:17 PM, <nicolas.capens@gmail.com> wrote:
> 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.
>
There is no way in practice to implicitly know when an object is okay to be
disposed of without the user providing such information.
On Wed, Aug 24, 2016 at 2:17 PM, <nicolas.capens@gmail.com> wrote:
> Anyway, for the use cases that I envision, the annotation at destructor
> declaration is appropriate. For example say I need a huge matrix to
> temporarily store some intermediate results. I could use "double
> matrix[10000][10000];" and rely on the compiler's optimizations to use the
> memory for other purposes as soon as I'm done with this matrix. But it's
> simply not going to fit on the stack. So instead I'll use an object with a
> pointer to heap memory. But now it only gets freed when it goes out of
> scope. 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.
>
Before again going into the subtleties of why annotation strictly at the
type level won't work, just think about what you've said -- the user would
have to use an equivalent type without eager destruction if they didn't
want this behavior. So now you have two types that do exactly the same
thing but one with an "eager" destructor? As I'll reiterate, the user
effectively needs to somehow notate at the usage point where they are done
with the object, but even if you don't get that argument, certainly your
desire for two equivalent types should hint to you that someone would at
least want to put the notation at the point of declaration of the *object*
that they want "eagerly" disposed of, instead of having it be a part of the
type. This removes the need for multiple types that you describe.
Anyway, apart from that, another simple example of where this breaks down:
you have your matrix type that you've described and some accessor taking a
row index and a column index. This function returns a reference to an
element of that matrix. Someone uses the function to access an element.
When is your matrix ready for disposal? Nobody is 'touching" your matrix
type immediately after you call that function, but a reference to one of
its elements still exists. Strictly speaking, the matrix could be "eagerly"
destroyed as soon as the accessor function returns, before the element is
even truly accessed through the reference. Even if you delay your disposal
until the end of the full expression, what happens if the reference is
stored and accessed in the next statement? This is not at all an
unreasonable scenario. Do you expect to track such references? If so, why
-- how would the compiler know which references to track. Is the compiler
expected to know that the reference which is returned corresponds to
something that is owned by the object that was accessed as opposed to just
a reference to some other, longer-lived double? What happens if, instead of
storing the reference, the result of the access is directly passed along as
an argument to another function? Would you just give up on eager
destruction there?
Ultimately, the user has the information that is needed and it is trivial
for them to specify, just as there is no problem with people writing things
like std::move today.
On Wed, Aug 24, 2016 at 2:17 PM, <nicolas.capens@gmail.com> wrote:
> For example, consider one of the kinds of types that you explicitly called
>> out: locks. A lock declaration has no actual knowledge of the memory that
>> it is effectively guarding, so there is no way to *actually* know when the
>> object is truly done with. Indeed, often times the object isn't even
>> touched directly *at all* once constructed. Prematurely destroying such an
>> object would be horrible. This issue is true of basically any object that
>> has a relationship with another object, such as iterators and their
>> associated container.
>>
>
> The solution here is to make the lock and the memory that it's guarding
> part of the same object.
>
This is not always feasible nor does it actually solve the problem.
On Wed, Aug 24, 2016 at 2:17 PM, <nicolas.capens@gmail.com> wrote:
> This issue is not very different from still having a reference to a local
> variable after it has gone out of scope. C++ is inherently unsafe, and you
> simply need to know what you're doing. With lazy destruction, don't use any
> references to the object after it has gone out of scope. With eager
> destruction, don't use any references to the object after its last use. A
> compiler warning could help prevent people from shooting themselves in the
> foot in both cases.
>
I'd argue that they are very different and it has everything to do with
your notion of "last use." This is not something that can actually be
detected, and if you rely on a naive notion of "use" being someone directly
touching the object, not even through a reference, then IMO it's
practically useless and extremely error prone.
I'm sorry if I sound overly negative here, but the problems of this are
already well understood. For any kind of early destruction in a language
like C++, users would need to be explicit, and that's not bad in this case.
I genuinely do believe that something similar to this is worthwhile, but
your particular approach is unrealistic (I think specifically that
destructive-move would solve a lot of problems with the language and
library as it is today).
--
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/CANh8DEkMPP-Wpc_DFxzHLpngYu%3D_8SmrArpBU8ARxUVjyN2_8A%40mail.gmail.com.
--94eb2c1244ca53e691053ad86ae6
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On W=
ed, Aug 24, 2016 at 2:17 PM, <span dir=3D"ltr"><<a href=3D"mailto:nicol=
as.capens@gmail.com" target=3D"_blank">nicolas.capens@gmail.com</a>></sp=
an> wrote:<br><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">On Wednesday, August 24, 2016 at 3:19:24 PM UTC-4, Matt Calabrese wro=
te:<span class=3D"gmail-"><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><div class=3D"gmail_quote"><div>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),</div></div></div></div></blockquote><div>=
<br></div></span><div>Yes, a destructive assignment could count as a last u=
se of its previous value and call the destructor that I'm proposing. I&=
#39;d also like it to be called after the last use as a source argument too=
though.</div></div></blockquote><div><br></div><div>Again, the problem is =
that "last use" isn't something that can actually be determin=
ed in any meaningful sense. For this to be usable, the *user* needs to nota=
te their last use by explicitly calling some kind of special destructive op=
eration that doesn't currently exist in the language (a hypothetical de=
structive move operation would be one of those special kinds of operations)=
.. I and others have given you examples of why what you want cannot be done =
truly automatically in a language like C++.</div><div><br></div><div>On Wed=
, Aug 24, 2016 at 2:17 PM,=C2=A0<span dir=3D"ltr"><<a href=3D"mailto:nic=
olas.capens@gmail.com" target=3D"_blank">nicolas.capens@gmail.com</a>></=
span>=C2=A0wrote:=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1=
ex"><div dir=3D"ltr"><span class=3D"gmail-"><blockquote class=3D"gmail_quot=
e" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204)=
;padding-left:1ex"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div>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 explic=
it 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></s=
pan><div>I wouldn't call it premature destruction. Eager instead of tod=
ay's lazy destruction at the end of the scope, seems like a better desc=
ription to me.</div></div></blockquote><div><br></div><div>There is no way =
in practice to implicitly know when an object is okay to be disposed of wit=
hout the user providing such information.</div><div><br></div><div>On Wed, =
Aug 24, 2016 at 2:17 PM,=C2=A0<span dir=3D"ltr"><<a href=3D"mailto:nicol=
as.capens@gmail.com" target=3D"_blank">nicolas.capens@gmail.com</a>></sp=
an>=C2=A0wrote:=C2=A0<br></div><blockquote class=3D"gmail_quote" style=3D"m=
argin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left=
:1ex"><div dir=3D"ltr"><div>Anyway, for the use cases that I envision, the =
annotation at destructor declaration is appropriate. For example say I need=
a huge matrix to temporarily store some intermediate results. I could use =
"double matrix[10000][10000];" and rely on the compiler's opt=
imizations to use the memory for other purposes as soon as I'm done wit=
h this matrix. But it's simply not going to fit on the stack. So instea=
d I'll use an object with a pointer to heap memory. But now it only get=
s freed when it goes out of scope. So I want to make it clear to the compil=
er 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 behavio=
r I can simply use an equivalent class without eager destructor.<br></div><=
/div></blockquote><div><br></div><div>Before again going into the subtletie=
s of why annotation strictly at the type level won't work, just think a=
bout what you've said -- the user would have to use an equivalent type =
without eager destruction if they didn't want this behavior. So now you=
have two types that do exactly the same thing but one with an "eager&=
quot; destructor? As I'll reiterate, the user effectively needs to some=
how notate at the usage point where they are done with the object, but even=
if you don't get that argument, certainly your desire for two equivale=
nt types should hint to you that someone would at least want to put the not=
ation at the point of declaration of the *object* that they want "eage=
rly" disposed of, instead of having it be a part of the type. This rem=
oves the need for multiple types that you describe.</div><div><br></div><di=
v>Anyway, apart from that, another simple example of where this breaks down=
: you have your matrix type that you've described and some accessor tak=
ing a row index and a column index. This function returns a reference to an=
element of that matrix. Someone uses the function to access an element. Wh=
en is your matrix ready for disposal? Nobody is 'touching" your ma=
trix type immediately after you call that function, but a reference to one =
of its elements still exists. Strictly speaking, the matrix could be "=
eagerly" destroyed as soon as the accessor function returns, before th=
e element is even truly accessed through the reference. Even if you delay y=
our disposal until the end of the full expression, what happens if the refe=
rence is stored and accessed in the next statement? This is not at all an u=
nreasonable scenario. Do you expect to track such references? If so, why --=
how would the compiler know which references to track. Is the compiler exp=
ected to know that the reference which is returned corresponds to something=
that is owned by the object that was accessed as opposed to just a referen=
ce to some other, longer-lived double? What happens if, instead of storing =
the reference, the result of the access is directly passed along as an argu=
ment to another function? Would you just give up on eager destruction there=
?</div><div><br></div><div>Ultimately, the user has the information that is=
needed and it is trivial for them to specify, just as there is no problem =
with people writing things like std::move today.</div><div><br></div><div>O=
n Wed, Aug 24, 2016 at 2:17 PM,=C2=A0<span dir=3D"ltr"><<a href=3D"mailt=
o:nicolas.capens@gmail.com" target=3D"_blank">nicolas.capens@gmail.com</a>&=
gt;</span>=C2=A0wrote:=C2=A0</div><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"><span class=3D"gmail-"><blockquote class=3D"gma=
il_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,2=
04,204);padding-left:1ex"><div dir=3D"ltr"><div><div class=3D"gmail_quote">=
<div>For example, consider one of the kinds of types that you explicitly ca=
lled out: locks. A lock declaration has no actual knowledge of the memory t=
hat it is effectively guarding, so there is no way to *actually* know when =
the object is truly done with. Indeed, often times the object isn't eve=
n touched directly *at all* once constructed. Prematurely destroying such a=
n object would be horrible. This issue is true of basically any object that=
has a relationship with another object, such as iterators and their associ=
ated container.</div></div></div></div></blockquote><div><br></div></span><=
div>The solution here is to make the lock and the memory that it's guar=
ding part of the same object.</div><span class=3D"gmail-"><div></div></span=
></div></blockquote><div><br></div><div>This is not always feasible nor doe=
s it actually solve the problem.</div><div><br></div><div>On Wed, Aug 24, 2=
016 at 2:17 PM,=C2=A0<span dir=3D"ltr"><<a href=3D"mailto:nicolas.capens=
@gmail.com" target=3D"_blank">nicolas.capens@gmail.com</a>></span>=C2=A0=
wrote:=C2=A0</div><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 di=
r=3D"ltr"><div>This issue is not very different from still having a referen=
ce to a local variable after it has gone out of scope. C++ is inherently un=
safe, and you simply need to know what you're doing. With lazy destruct=
ion, don't use any references to the object after it has gone out of sc=
ope. With eager destruction, don't use any references to the object aft=
er its last use. A compiler warning could help prevent people from shooting=
themselves in the foot in both cases.</div></div></blockquote><div><br></d=
iv><div>I'd argue that they are very different and it has everything to=
do with your notion of "last use." This is not something that ca=
n actually be detected, and if you rely on a naive notion of "use"=
; being someone directly touching the object, not even through a reference,=
then IMO it's practically useless and extremely error prone.</div><div=
><br></div><div>I'm sorry if I sound overly negative here, but the prob=
lems of this are already well understood. For any kind of early destruction=
in a language like C++, users would need to be explicit, and that's no=
t bad in this case. I genuinely do believe that something similar to this i=
s worthwhile, but your particular approach is unrealistic (I think specific=
ally that destructive-move would solve a lot of problems with the language =
and library as it is today).</div></div></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/CANh8DEkMPP-Wpc_DFxzHLpngYu%3D_8SmrAr=
pBU8ARxUVjyN2_8A%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANh8DEkMPP-Wpc=
_DFxzHLpngYu%3D_8SmrArpBU8ARxUVjyN2_8A%40mail.gmail.com</a>.<br />
--94eb2c1244ca53e691053ad86ae6--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 24 Aug 2016 15:05:38 -0700 (PDT)
Raw View
------=_Part_16_1816603948.1472076338224
Content-Type: multipart/alternative;
boundary="----=_Part_17_43821072.1472076338229"
------=_Part_17_43821072.1472076338229
Content-Type: text/plain; charset=UTF-8
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.
The ability to execute the destructor and simultaneously prevent the
compiler from doing so is something that can be discussed and debated. But
as Matt said, it would be explicit at the point of use, not implicitly
built into the type. The code that wants to change the default behavior,
which is the code that gains certain responsibilities by doing so, is the
code *using* the object, not the code *defining* it.
Putting it in the type is simply the wrong place for it. It's the code that
needs the optimization who should be responsible for invoking this behavior.
Anyway, for the use cases that I envision, the annotation at destructor
> declaration is appropriate. For example say I need a huge matrix to
> temporarily store some intermediate results. I could use "double
> matrix[10000][10000];" and rely on the compiler's optimizations to use the
> memory for other purposes as soon as I'm done with this matrix. But it's
> simply not going to fit on the stack. So instead I'll use an object with a
> pointer to heap memory. But now it only gets freed when it goes out of
> scope.
>
No, it gets freed when you want it to be freed. Observe:
auto heap_allocation = std::make_unique<T>(...);
//use the object
heap_allocation.reset();
See? it's been freed after the last use.
This way, you don't have to play games of wondering exactly when the
allocation is destroyed. It's destroyed when you *destroy 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.
> 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.
Even with that, you might think that it's okay to annotate types that
>> contain no logical relationships to objects that it does not own. For
>> instance, something that just contains an int or a unique_ptr to some
>> object with no relationships, etc. The problem is, even in these cases,
>> there is nothing stopping some *other* object from storing a pointer or
>> reference to an instance of your
>> automatically-prematurely-destructible-type. If someone *does* hold such a
>> reference and your annotated type is "no longer used", then the object that
>> refers to it will now have a dangling reference. Point being, your
>> annotation cannot be at the type level.
>>
>
> This issue is not very different from still having a reference to a local
> variable after it has gone out of scope. C++ is inherently unsafe, and you
> simply need to know what you're doing. With lazy destruction, don't use any
> references to the object after it has gone out of scope. With eager
> destruction, don't use any references to the object after its last use. A
> compiler warning could help prevent people from shooting themselves in the
> foot in both cases.
>
What would trigger such a warning? Passing a variable of such a type as a
reference to someone else? Because that's all the compiler can know: that a
reference or pointer was passed to some function. It has no idea if that
function retains that value or not, or when it is expected to relinquish it.
You'd need serious static analysis to avoid a litany of false positives.
>
>
--
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/4387866d-169e-44a8-a858-d9aa96d54680%40isocpp.org.
------=_Part_17_43821072.1472076338229
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Wednesday, August 24, 2016 at 5:17:26 PM UTC-4, nicolas=
....@gmail.com wrote:<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">On Wednesday, August 24, 2016 at 3:19:24 PM UTC-4, Matt Calabrese =
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"><div><div cl=
ass=3D"gmail_quote">On Wed, Aug 24, 2016 at 11:51 AM, <span dir=3D"ltr">&l=
t;<a rel=3D"nofollow">nicolas...@gmail.com</a>></span> wrote:<br><blockq=
uote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc =
solid;padding-left:1ex"><div dir=3D"ltr"><div>Hi all,</div><div><br></div>I=
'd like to propose a new kind of destructor that gets called after a lo=
cal object's last use, instead of at the end of its scope.<div><br></di=
v><div>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 resul=
t in more efficient programs.</div><div><br></div><div>Currently such optim=
ization can only be achieved by explicitly releasing the resources, which i=
s inconvenient, bug prone, and reduces readability. Limiting the scope with=
extra braces or by putting the operations in a subroutine also often isn&#=
39;t a desirable workaround. Note that compilers have been doing liveness a=
nalysis for register allocation and stack compaction for a very long time a=
nd we take these optimizations for granted. I'd like to see it get exte=
nded to heap memory and other resources as well.</div><div><span style=3D"l=
ine-height:17px"><br></span></div><div>The s<span style=3D"line-height:17px=
">yntax 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();".</span></div><div><span style=3D"line-height:17px"><br><=
/span></div><div><span style=3D"line-height:17px">Thoughts?</span></div></d=
iv></blockquote><div><br></div><div>While I would like C++ to eventually ge=
t a way to do the equivalent of this in some form (more generally, I want d=
estructive move, which is related to this even though it may not be immedia=
tely obvious),</div></div></div></div></blockquote><div><br></div><div>Yes,=
a destructive assignment could count as a last use of its previous value a=
nd call the destructor that I'm proposing. I'd also like it to be c=
alled after the last use as a source argument too though.</div><div>=C2=A0<=
/div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;=
border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><div cla=
ss=3D"gmail_quote"><div>I do not think that the appropriate place to notate=
the premature destruction is on the destructor declaration. Instead, I bel=
ieve it needs to be explicit at the usage-site. This is primarily because w=
e are in a language where side-effects matter.</div></div></div></div></blo=
ckquote><div><br></div><div>I wouldn't call it premature destruction. E=
ager instead of today's lazy destruction at the end of the scope, seems=
like a better description to me.</div></div></blockquote><div><br>Playing =
word games doesn't change the fact that the standard makes it clear tha=
t destruction of an automatic object happens in a single, well-defined plac=
e. Your proposal wants to *transparently* change that location based on som=
ething in the type of that object.<br><br>The ability to execute the destru=
ctor and simultaneously prevent the compiler from doing so is something tha=
t can be discussed and debated. But as Matt said, it would be explicit at t=
he point of use, not implicitly built into the type. The code that wants to=
change the default behavior, which is the code that gains certain responsi=
bilities by doing so, is the code <i>using</i> the object, not the code <i>=
defining</i> it.<br><br>Putting it in the type is simply the wrong place fo=
r it. It's the code that needs the optimization who should be responsib=
le for invoking this behavior.<br><br></div><blockquote class=3D"gmail_quot=
e" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddin=
g-left: 1ex;"><div dir=3D"ltr"><div></div><div>Anyway, for the use cases th=
at I envision, the annotation at destructor declaration is appropriate. For=
example say I need a huge matrix to temporarily store some intermediate re=
sults. I could use "double matrix[10000][10000];" and rely on the=
compiler's optimizations to use the memory for other purposes as soon =
as I'm done with this matrix. But it's simply not going to fit on t=
he stack. So instead I'll use an object with a pointer to heap memory. =
But now it only gets freed when it goes out of scope.</div></div></blockquo=
te><div><br>No, it gets freed when you want it to be freed. Observe:<br><br=
><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); =
border-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; w=
ord-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subprettyp=
rint"><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> heap_allocation =
</span><span style=3D"color: #660;" class=3D"styled-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-prettify">::</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify">make_unique</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=3D"co=
lor: #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><br></span><span style=3D"color: #800;"=
class=3D"styled-by-prettify">//use the object</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"><br><br>heap_allocation</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">.</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">reset</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">();</span></div></code></div><br>See? it=
's been freed after the last use.<br><br>This way, you don't have t=
o play games of wondering exactly when the allocation is destroyed. It'=
s destroyed when you <i>destroy it</i>.<br><br>You can explicitly reset sma=
rt pointers; you can explicitly close streams. And for moveable types that =
don't offer such features, Magnus gave a great answer:<br><br><div clas=
s=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); border-col=
or: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: =
break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><spa=
n style=3D"color: #606;" class=3D"styled-by-prettify">Object</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"co=
lor: #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">move</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">auto_val</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">));</span></div></code></div><br>That works for pretty much any mo=
veable `Object` type that represents a resource.<br><br>The point in time w=
hen an automatic variable is destroyed should not be a <i>mystery</i>. It s=
hould never be in question when an automatic variable is no longer a legiti=
mate object.<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><d=
iv dir=3D"ltr"><div>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 i=
nstance. It's a property of the class itself that I want it's destr=
uctor to be called eagerly. If I don't want that behavior I can simply =
use an equivalent class without eager destructor.</div></div></blockquote><=
div><br>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 <i>only</i> b=
y the presence or absence of "eager destruction". We don't wa=
nt `eager_unique_ptr` or `eager_ifstream` or `eager_vector` or whatever.<br=
><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left=
: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><d=
iv> </div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0=
..8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><di=
v class=3D"gmail_quote"><div>Even with that, you might think that it's =
okay to annotate types that contain no logical relationships to objects tha=
t it does not own. For instance, something that just contains an int or a u=
nique_ptr to some object with no relationships, etc. The problem is, even i=
n these cases, there is nothing stopping some *other* object from storing a=
pointer or reference to an instance of your automatically-prematurely-<wbr=
>destructible-type. If someone *does* hold such a reference and your annota=
ted type is "no longer used", then the object that refers to it w=
ill now have a dangling reference. Point being, your annotation cannot be a=
t the type level.</div></div></div></div></blockquote><div><br></div><div>T=
his issue is not very different from still having a reference to a local va=
riable after it has gone out of scope. C++ is inherently unsafe, and you si=
mply need to know what you're doing. With lazy destruction, don't u=
se any references to the object after it has gone out of scope. With eager =
destruction, don't use any references to the object after its last use.=
A compiler warning could help prevent people from shooting themselves in t=
he foot in both cases.</div></div></blockquote><div dir=3D"ltr"><br>What wo=
uld trigger such a warning? Passing a variable of such a type as a referenc=
e to someone else? Because that's all the compiler can know: that a ref=
erence or pointer was passed to some function. It has no idea if that funct=
ion retains that value or not, or when it is expected to relinquish it.<br>=
<br>You'd need serious static analysis to avoid a litany of false posit=
ives.<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;=
border-left:1px #ccc solid;padding-left:1ex">
</blockquote></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/4387866d-169e-44a8-a858-d9aa96d54680%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/4387866d-169e-44a8-a858-d9aa96d54680=
%40isocpp.org</a>.<br />
------=_Part_17_43821072.1472076338229--
------=_Part_16_1816603948.1472076338224--
.
Author: Thiago Macieira <thiago@macieira.org>
Date: Wed, 24 Aug 2016 15:41:22 -0700
Raw View
Em quarta-feira, 24 de agosto de 2016, =C3=A0s 13:16:30 PDT,=20
nicolas.capens@gmail.com escreveu:
> > Define "last use".=20
>=20
> The last use according to liveness analysis.
Let's make it stricter: the last time the object is formally ODR-used.
But then, what happens to lifetime extension via references?
resource a;
const resource &r =3D a;
When does a get destroyed?
--=20
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
--=20
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 e=
mail 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/2167954.HnHgbLeUUh%40tjmaciei-mobl1.
.
Author: Viacheslav Usov <via.usov@gmail.com>
Date: Thu, 25 Aug 2016 12:37:37 +0200
Raw View
--001a114025cc96d98d053ae2fc52
Content-Type: text/plain; charset=UTF-8
On Wed, Aug 24, 2016 at 8:51 PM, <nicolas.capens@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 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/CAA7YVg3dJT3LY_L5Eg%3DZNgfqqyOcX9P%3DJVv_pXTEx6xxsoGOdg%40mail.gmail.com.
--001a114025cc96d98d053ae2fc52
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On W=
ed, Aug 24, 2016 at 8:51 PM, <span dir=3D"ltr"><<a href=3D"mailto:nicol=
as.capens@gmail.com" target=3D"_blank">nicolas.capens@gmail.com</a>></sp=
an> wrote:</div><div class=3D"gmail_quote"><br></div><div class=3D"gmail_qu=
ote">>=C2=A0<span style=3D"font-size:12.8px">I'd like to propose a n=
ew kind of destructor that gets called after a local object's last use,=
instead of at the end of its scope.</span></div><div class=3D"gmail_quote"=
><br></div><div class=3D"gmail_quote"><span style=3D"line-height:17px">&quo=
t;Destruct after last use" is generally known as "garbage collect=
ion". 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 s=
cope rules, simple and hugely successful. The question, then, is whether we=
really need another=C2=A0competing=C2=A0definition, and whether we really =
gain much with that additional complexity.</span><br></div><div class=3D"gm=
ail_quote"><span style=3D"line-height:17px"><br></span></div><div class=3D"=
gmail_quote"><span style=3D"line-height:17px">Note I'm not assuming you=
would propose a non-deterministic=C2=A0definition.</span></div><div class=
=3D"gmail_quote"><br></div><div class=3D"gmail_quote">> The s<span style=
=3D"line-height:17px">yntax for this could be an annotation of the destruct=
or declaration with a keyword, symbol, or attribute. For example, "aut=
o ~Object();", "volatile ~Object();", "~~Object();"=
;, or "[[eager]] ~Object();".</span></div><div class=3D"gmail_quo=
te"><span style=3D"line-height:17px"><br></span></div><div class=3D"gmail_q=
uote"><span style=3D"line-height:17px">The assumption that one can decorate=
a <i>class</i> definition with "destruct after last use" seems o=
verly optimistic to me. </span>Letting the users of the class decorate 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>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/CAA7YVg3dJT3LY_L5Eg%3DZNgfqqyOcX9P%3D=
JVv_pXTEx6xxsoGOdg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAA7YVg3dJT3L=
Y_L5Eg%3DZNgfqqyOcX9P%3DJVv_pXTEx6xxsoGOdg%40mail.gmail.com</a>.<br />
--001a114025cc96d98d053ae2fc52--
.
Author: Nicolas Capens <nicolas.capens@gmail.com>
Date: Thu, 25 Aug 2016 21:24:27 +0000
Raw View
--001a11403430693178053aec06e7
Content-Type: text/plain; charset=UTF-8
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.usov@gmail.com> wrote:
> On Wed, Aug 24, 2016 at 8:51 PM, <nicolas.capens@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-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/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/CAE7XuEWr7eyyjmqURnMwQf1pvyvHeMATM1MDjRY%3D25WuGy5Z%3Dw%40mail.gmail.com.
--001a11403430693178053aec06e7
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Thanks all for the initial feedback! It's clear to me =
now that I haven't defined "last use" very well, and giving i=
t 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 desc=
ribe what real-world issues I'm trying to solve. The first example is o=
ne 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 availab=
le for a different variable:</div><div><br></div><div><font face=3D"monospa=
ce">=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'000, 10'000) =3D ...;</font></div><div><font face=
=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 Matrix b(10'000, 10'000)=
=3D ...;<br></font></div><div><font face=3D"monospace">=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 Matrix c(10'000, 10'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 dir=3D"ltr"><div>The alt=
ernative of using explicit destruction is really inconvenient:</div><div><b=
r></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'000, =
10'000) =3D ...;</font></div><div><font face=3D"monospace">=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 Matrix b(10'000, 10'000) =3D ...;<br></font></div=
><div><font face=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 Matrix c(10'=
000, 10'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"monospace">=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"monospac=
e">=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"monospace">=C2=A0 =C2=
=A0 {</font></div><div><font face=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0=
Matrix a(10'000, 10'000) =3D ...;</font></div><div><font face=3D"m=
onospace"><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'000, 10'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 class=3D"inbox-i=
nbox-Apple-interchange-newline">=C2=A0 =C2=A0 =C2=A0 =C2=A0 Matrix c(10'=
;000, 10'000) =3D ...;=C2=A0=C2=A0<br></font></div><div><font face=3D"m=
onospace">=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 class=3D"gm=
ail_extra"><br></div><div class=3D"gmail_extra">It might not look that horr=
ible when we're only dealing with one variable that can be destructed e=
agerly, but it quickly gets unmanageable to manually optimize code like thi=
s when using additional variables and longer expressions. So I wish to be a=
ble to convey to the compiler that my Matrix class is self-contained and ca=
n in have its destructor called before the end of the object's scope.</=
div><div class=3D"gmail_extra"><br></div><div class=3D"gmail_extra">Obvious=
ly 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&=
#39;s innards and use that to extend its lifetime. But taking a reference t=
o the object itself can easily be determined, just like is done with scalar=
variables to extend their liveness range.</div><div class=3D"gmail_extra">=
<br></div><div class=3D"gmail_extra">A second use case I have for this is t=
o reduce the run-time optimization work of an EDSL used for JIT-compiling c=
ode: <a href=3D"https://swiftshader.googlesource.com/SwiftShader/+/HEAD/doc=
s/Reactor.md">Reactor</a>. The types that are used=C2=A0<i>represent</i> sc=
alar variables (e.g. <font face=3D"monospace">Int</font> represents <font f=
ace=3D"monospace">int</font>), but have a complex implementation to keep tr=
ack of the operations performed on them to later be used to generate code f=
rom. If the static C++ compiler called their destructor on their last use a=
s the scalar they represent, optimizing the run-time generated code could b=
e quicker.</div><div class=3D"gmail_extra"><br></div><div class=3D"gmail_ex=
tra">As for an example of optimizing mutex locking, take a class which take=
s exclusive ownership of a stream so you can write contiguous data to it:</=
div><div class=3D"gmail_extra"><br></div><div class=3D"gmail_extra"><font f=
ace=3D"monospace">=C2=A0 =C2=A0 {</font></div><div class=3D"gmail_extra"><f=
ont face=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 Streamer s(stream);</fon=
t></div><div class=3D"gmail_extra"><font face=3D"monospace">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 s.write("200");</font></div><div class=3D"gmail_ext=
ra"><font face=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 s.write(" OK&=
quot;); =C2=A0 // Last use, call destructor which releases exclusive owners=
hip so another thread can write something.</font></div><div class=3D"gmail_=
extra"><font face=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 do_something_el=
se_before_end_of_scope();</font></div><div class=3D"gmail_extra"><font face=
=3D"monospace">=C2=A0 =C2=A0 }</font></div><div class=3D"gmail_extra"><br><=
/div><div class=3D"gmail_extra">Of course in this trivial case you might ju=
st write "200 OK" in one go, but imagine a much lager stream of d=
ata that is composed of an unknown number of parts. There would be an overh=
ead from allocating and reallocating storage for the whole. Also, if the re=
ader of the stream can handle partial data then we don't want to delay =
streaming out the parts.</div><div class=3D"gmail_extra"><br></div><div cla=
ss=3D"gmail_extra">So I hope this illustrates what I'm after. I'm c=
onvinced there's an unambiguous definition of "last use" that=
can provide us with the desired behavior in all of the above examples, wit=
hout undue burden on the compiler's analysis. I think liveness analysis=
when treating the object as a scalar would give us all we need.</div><div =
class=3D"gmail_extra"><br></div><div class=3D"gmail_extra">One question I h=
ave though is whether liveness analysis of scalars is a "solved proble=
m"? In other words are all optimizing compilers capable of producing e=
quivalent, deterministic liveness analysis? If not, I still think a <i>cons=
ervative</i> eager destructor would be a great thing to have to optimize th=
e above use cases. I don't think determinism is strictly necessary, sin=
ce compilers already produce code that can behave differently depending on =
optimizations.</div><div class=3D"gmail_extra"><br></div><div class=3D"gmai=
l_extra">Thanks again!</div><div class=3D"gmail_extra">- Nicolas</div><div =
class=3D"gmail_extra"><br></div><div class=3D"gmail_extra"><div class=3D"gm=
ail_quote">On Thu, Aug 25, 2016 at 6:37 AM, Viacheslav Usov <span dir=3D"lt=
r"><<a href=3D"mailto:via.usov@gmail.com" target=3D"_blank">via.usov@gma=
il.com</a>></span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"=
margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-lef=
t:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><span><div class=3D"gmai=
l_quote">On Wed, Aug 24, 2016 at 8:51 PM, <span dir=3D"ltr"><<a href=3D=
"mailto:nicolas.capens@gmail.com" target=3D"_blank">nicolas.capens@gmail.co=
m</a>></span> wrote:</div><div class=3D"gmail_quote"><br></div><div clas=
s=3D"gmail_quote">>=C2=A0<span style=3D"font-size:12.8px">I'd like t=
o propose a new kind of destructor that gets called after a local object=
9;s last use, instead of at the end of its scope.</span></div><div class=3D=
"gmail_quote"><br></div></span><div class=3D"gmail_quote"><span style=3D"li=
ne-height:17px">"Destruct after last use" is generally known as &=
quot;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, i=
t is the automatic scope rules, simple and hugely successful. The question,=
then, is whether we really need another=C2=A0competing=C2=A0definition, an=
d whether we really gain much with that additional complexity.</span><br></=
div><div class=3D"gmail_quote"><span style=3D"line-height:17px"><br></span>=
</div><div class=3D"gmail_quote"><span style=3D"line-height:17px">Note I=
9;m not assuming you would propose a non-deterministic=C2=A0definition.</sp=
an></div><span><div class=3D"gmail_quote"><br></div><div class=3D"gmail_quo=
te">> The s<span style=3D"line-height:17px">yntax for this could be an a=
nnotation of the destructor declaration with a keyword, symbol, or attribut=
e. For example, "auto ~Object();", "volatile ~Object();"=
;, "~~Object();", or "[[eager]] ~Object();".</span></di=
v><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 can decorate a <i>class</i> definition with "destr=
uct after last use" seems overly optimistic to me. </span>Letting the =
users of the class decorate the <i>object</i> definition as such seems more=
reasonable.<br></div><div class=3D"gmail_quote"><br></div><div class=3D"gm=
ail_quote">Cheers,<br></div><div class=3D"gmail_quote">V.</div></div></div>=
<span>
<p></p>
-- <br>
You received this message because you are subscribed to a topic in the Goog=
le Groups "ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/IUxA4cx8yHc/unsubscribe" target=3D"_blan=
k">https://groups.google.com/a/isocpp.org/d/topic/std-proposals/IUxA4cx8yHc=
/unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a href=
=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_blank">std-prop=
osals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></span>
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&utm_source=3Dfoo=
ter" target=3D"_blank">https://groups.google.com/a/isocpp.org/d/msgid/std-p=
roposals/CAA7YVg3dJT3LY_L5Eg%3DZNgfqqyOcX9P%3DJVv_pXTEx6xxsoGOdg%40mail.gma=
il.com</a>.<br>
</blockquote></div><br></div></div></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/CAE7XuEWr7eyyjmqURnMwQf1pvyvHeMATM1MD=
jRY%3D25WuGy5Z%3Dw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAE7XuEWr7eyy=
jmqURnMwQf1pvyvHeMATM1MDjRY%3D25WuGy5Z%3Dw%40mail.gmail.com</a>.<br />
--001a11403430693178053aec06e7--
.
Author: btcrtn@gmail.com
Date: Thu, 25 Aug 2016 14:35:32 -0700 (PDT)
Raw View
------=_Part_1155_1678812654.1472160932534
Content-Type: multipart/alternative;
boundary="----=_Part_1156_72454644.1472160932535"
------=_Part_1156_72454644.1472160932535
Content-Type: text/plain; charset=UTF-8
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 */
}
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
> <javascript:>> wrote:
>
>> On Wed, Aug 24, 2016 at 8:51 PM, <nicolas...@gmail.com <javascript:>>
>> 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 <javascript:>.
>> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
>> 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/371d0b28-0593-4f79-9c05-1e9540cc4e2c%40isocpp.org.
------=_Part_1156_72454644.1472160932535
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Would it not be convenient enough to define a helper funct=
ion? Would the following work?<br><br><div class=3D"prettyprint" style=3D"b=
ackground-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); bord=
er-style: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"=
prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">template</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify"><</span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">class</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> T</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">></span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">void</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> finish</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">T</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">&&</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> x</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> y</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify">std</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">move</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">x</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: #660;" class=3D"st=
yled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br><br></span><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">void</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> f</span><span style=3D"color: #660;" class=3D"styled-by-prettify">()</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><sp=
an style=3D"color: #606;" class=3D"styled-by-prettify">MyExpe</span><span s=
tyle=3D"color: #606;" class=3D"styled-by-prettify">nsiveResource</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> r</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=
=3D"color: #800;" class=3D"styled-by-prettify">/* code */</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 finish</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify">r</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #800;" cla=
ss=3D"styled-by-prettify">// 'r' is not needed anymore.</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </sp=
an><span style=3D"color: #800;" class=3D"styled-by-prettify">/* code */</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">}</span></div></code=
></div><br><br><br><br><br>On Thursday, August 25, 2016 at 11:24:39 PM UTC+=
2, Nicolas Capens wrote:<blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div d=
ir=3D"ltr">Thanks all for the initial feedback! It's clear to me now th=
at I haven't defined "last use" very well, and giving it an a=
ccurate 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 describe w=
hat real-world issues I'm trying to solve. The first example is one whe=
re I'd like the heap memory managed by an object to get freed at the sa=
me point where a scalar variable's register would be made available for=
a different variable:</div><div><br></div><div><font face=3D"monospace">=
=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 public:</=
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"monospace">=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 auto ~Matrix(); =C2=A0 // Eager destructor</fon=
t></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><di=
v><font face=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 double *m;</font></d=
iv><div><font face=3D"monospace">=C2=A0 =C2=A0 };</font></div><div><font fa=
ce=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'000, 10'000) =3D ...;</font></div><div><font face=3D"m=
onospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 Matrix b(10'000, 10'000) =3D =
....;<br></font></div><div><font face=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 Matrix c(10'000, 10'000) =3D ...;<br></font></div><div><font fa=
ce=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 before t=
he 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 dir=3D"ltr"><div>The alternativ=
e of using explicit destruction is really inconvenient:</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'000, 10'=
000) =3D ...;</font></div><div><font face=3D"monospace">=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 Matrix b(10'000, 10'000) =3D ...;<br></font></div><div><=
font face=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 Matrix c(10'000, 10=
'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"monospace">=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"monospace">=C2=A0 =C2=A0 {</f=
ont></div><div><font face=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 Matrix =
a(10'000, 10'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'000, 10'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'000, 10'000) =3D ...;=C2=A0=C2=A0<br></font></di=
v><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><br></div><div>It might not look that horrible when we're on=
ly dealing with one variable that can be destructed eagerly, but it quickly=
gets unmanageable to manually optimize code like this when using additiona=
l variables and longer expressions. So I wish to be able to convey to the c=
ompiler that my Matrix class is self-contained and can in have its destruct=
or called before the end of the object's scope.</div><div><br></div><di=
v>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 t=
o require the compiler to determine if we're obtaining references to th=
e object's innards and use that to extend its lifetime. But taking a re=
ference to the object itself can easily be determined, just like is done wi=
th scalar variables to extend their liveness range.</div><div><br></div><di=
v>A second use case I have for this is to reduce the run-time optimization =
work of an EDSL used for JIT-compiling code: <a href=3D"https://swiftshader=
..googlesource.com/SwiftShader/+/HEAD/docs/Reactor.md" target=3D"_blank" rel=
=3D"nofollow" onmousedown=3D"this.href=3D'https://swiftshader.googlesou=
rce.com/SwiftShader/+/HEAD/docs/Reactor.md';return true;" onclick=3D"th=
is.href=3D'https://swiftshader.googlesource.com/SwiftShader/+/HEAD/docs=
/Reactor.md';return true;">Reactor</a>. The types that are used=C2=A0<i=
>represent</i> scalar variables (e.g. <font face=3D"monospace">Int</font> r=
epresents <font face=3D"monospace">int</font>), but have a complex implemen=
tation to keep track of the operations performed on them to later be used t=
o generate code from. If the static C++ compiler called their destructor on=
their last use as the scalar they represent, optimizing the run-time gener=
ated code could be quicker.</div><div><br></div><div>As for an example of o=
ptimizing mutex locking, take a class which takes exclusive ownership of a =
stream so you can write contiguous data to it:</div><div><br></div><div><fo=
nt face=3D"monospace">=C2=A0 =C2=A0 {</font></div><div><font face=3D"monosp=
ace">=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("200");</=
font></div><div><font face=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 s.writ=
e(" OK"); =C2=A0 // Last use, call destructor which releases excl=
usive ownership so another thread can write something.</font></div><div><fo=
nt face=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 do_something_else_before_=
end_<wbr>of_scope();</font></div><div><font face=3D"monospace">=C2=A0 =C2=
=A0 }</font></div><div><br></div><div>Of course in this trivial case you mi=
ght just write "200 OK" in one go, but imagine a much lager strea=
m 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.</div><div><br></div><div>So I hope this illu=
strates what I'm after. I'm convinced there's an unambiguous de=
finition of "last use" that can provide us with the desired behav=
ior 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.</div><div><br></div><div>One question I have tho=
ugh is whether liveness analysis of scalars is a "solved problem"=
? In other words are all optimizing compilers capable of producing equivale=
nt, deterministic liveness analysis? If not, I still think a <i>conservativ=
e</i> eager destructor would be a great thing to have to optimize the above=
use cases. I don't think determinism is strictly necessary, since comp=
ilers already produce code that can behave differently depending on optimiz=
ations.</div><div><br></div><div>Thanks again!</div><div>- Nicolas</div><di=
v><br></div><div><div class=3D"gmail_quote">On Thu, Aug 25, 2016 at 6:37 AM=
, Viacheslav Usov <span dir=3D"ltr"><<a href=3D"javascript:" target=3D"_=
blank" gdf-obfuscated-mailto=3D"yKNqKl8hDgAJ" rel=3D"nofollow" onmousedown=
=3D"this.href=3D'javascript:';return true;" onclick=3D"this.href=3D=
'javascript:';return true;">via....@gmail.com</a>></span> wrote:=
<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bor=
der-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div=
><span><div class=3D"gmail_quote">On Wed, Aug 24, 2016 at 8:51 PM, <span d=
ir=3D"ltr"><<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mai=
lto=3D"yKNqKl8hDgAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javas=
cript:';return true;" onclick=3D"this.href=3D'javascript:';retu=
rn true;">nicolas...@gmail.com</a>></span> wrote:</div><div class=3D"gma=
il_quote"><br></div><div class=3D"gmail_quote">>=C2=A0<span style=3D"fon=
t-size:12.8px">I'd like to propose a new kind of destructor that gets c=
alled after a local object's last use, instead of at the end of its sco=
pe.</span></div><div class=3D"gmail_quote"><br></div></span><div class=3D"g=
mail_quote"><span style=3D"line-height:17px">"Destruct after last use&=
quot; is generally known as "garbage collection". There is no kno=
wn deterministic solution to this general problem. This is what many other =
comments have been about. You can only make this deterministic if you provi=
de some narrow definition of "last use". C++ has such a narrow de=
finition for local objects, it is the automatic scope rules, simple and hug=
ely successful. The question, then, is whether we really need another=C2=A0=
competing=C2=A0definition, and whether we really gain much with that additi=
onal complexity.</span><br></div><div class=3D"gmail_quote"><span style=3D"=
line-height:17px"><br></span></div><div class=3D"gmail_quote"><span style=
=3D"line-height:17px">Note I'm not assuming you would propose a non-det=
erministic=C2=A0definition.</span></div><span><div class=3D"gmail_quote"><b=
r></div><div class=3D"gmail_quote">> The s<span style=3D"line-height:17p=
x">yntax 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();".</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 can decorate a <i>class<=
/i> definition with "destruct after last use" seems overly optimi=
stic to me. </span>Letting the users of the class decorate the <i>object</i=
> definition as such seems more reasonable.<br></div><div class=3D"gmail_qu=
ote"><br></div><div class=3D"gmail_quote">Cheers,<br></div><div class=3D"gm=
ail_quote">V.</div></div></div><span>
<p></p>
-- <br>
You received this message because you are subscribed to a topic in the Goog=
le Groups "ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/IUxA4cx8yHc/unsubscribe" target=3D"_blan=
k" rel=3D"nofollow" onmousedown=3D"this.href=3D'https://groups.google.c=
om/a/isocpp.org/d/topic/std-proposals/IUxA4cx8yHc/unsubscribe';return t=
rue;" onclick=3D"this.href=3D'https://groups.google.com/a/isocpp.org/d/=
topic/std-proposals/IUxA4cx8yHc/unsubscribe';return true;">https://grou=
ps.google.com/a/<wbr>isocpp.org/d/topic/std-<wbr>proposals/IUxA4cx8yHc/<wbr=
>unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a href=
=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"yKNqKl8hDgAJ" r=
el=3D"nofollow" onmousedown=3D"this.href=3D'javascript:';return tru=
e;" onclick=3D"this.href=3D'javascript:';return true;">std-proposal=
....@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"javascript:" target=3D"_bla=
nk" gdf-obfuscated-mailto=3D"yKNqKl8hDgAJ" rel=3D"nofollow" onmousedown=3D"=
this.href=3D'javascript:';return true;" onclick=3D"this.href=3D'=
;javascript:';return true;">std-pr...@isocpp.org</a>.<br></span>
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&utm_source=3Dfoo=
ter" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D'htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAA7YVg3dJT3LY_L5=
Eg%3DZNgfqqyOcX9P%3DJVv_pXTEx6xxsoGOdg%40mail.gmail.com?utm_medium\x3demail=
\x26utm_source\x3dfooter';return true;" onclick=3D"this.href=3D'htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAA7YVg3dJT3LY_L5=
Eg%3DZNgfqqyOcX9P%3DJVv_pXTEx6xxsoGOdg%40mail.gmail.com?utm_medium\x3demail=
\x26utm_source\x3dfooter';return true;">https://groups.google.com/a/<wb=
r>isocpp.org/d/msgid/std-<wbr>proposals/CAA7YVg3dJT3LY_L5Eg%<wbr>3DZNgfqqyO=
cX9P%3DJVv_<wbr>pXTEx6xxsoGOdg%40mail.gmail.<wbr>com</a>.<br>
</blockquote></div><br></div></div></div></div>
</blockquote></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/371d0b28-0593-4f79-9c05-1e9540cc4e2c%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/371d0b28-0593-4f79-9c05-1e9540cc4e2c=
%40isocpp.org</a>.<br />
------=_Part_1156_72454644.1472160932535--
------=_Part_1155_1678812654.1472160932534--
.
Author: Nicolas Capens <nicolas.capens@gmail.com>
Date: Fri, 26 Aug 2016 14:57:24 +0000
Raw View
--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 <<a href=3D"mailto:btcrtn@gmail.com">btcrtn@gmail.com<=
/a>> 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"><</span><span style=3D"color:#008">class</span><span style=3D"c=
olor:#000"> T</span><span style=3D"color:#660">></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">&&</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' 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'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's unaccepta=
ble 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.</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's clear to m=
e 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.<div><br></div><div>So let me take a step back and de=
scribe 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 a=
t the same point where a scalar variable'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'000, 10'000) =3D ...;</font></div><div><font face=
=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 Matrix b(10'000, 10'000)=
=3D ...;<br></font></div><div><font face=3D"monospace">=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 Matrix c(10'000, 10'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'000, 10'000) =3D ...;</font></div><div><font face=
=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 Matrix b(10'000, 10'000)=
=3D ...;<br></font></div><div><font face=3D"monospace">=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 Matrix c(10'000, 10'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'000, 10'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'000, 10'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'000, 10'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'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'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'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 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("200");</font></div><div><fo=
nt face=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 s.write(" OK");=
=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 "200 O=
K" 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't want to delay streaming out the pa=
rts.</div><div><br></div><div>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 ex=
amples, without undue burden on the compiler'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 "solved problem"? 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'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"><<a =
rel=3D"nofollow">via....@gmail.com</a>></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"><<a rel=3D"nofollow">nicolas...@gmail.com</a>></span> wrote:=
</div><div class=3D"gmail_quote"><br></div><div class=3D"gmail_quote">>=
=C2=A0<span style=3D"font-size:12.8px">I'd like to propose a new kind o=
f destructor that gets called after a local object'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">"=
Destruct after last use" is generally known as "garbage collectio=
n". 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 "last use". =
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'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">> 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, "=
auto ~Object();", "volatile ~Object();", "~~Object();&q=
uot;, or "[[eager]] ~Object();".</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 "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 "ISO C++ Standard - Future Proposals" 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&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" 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--
.
Author: Nicolas Capens <nicolas.capens@gmail.com>
Date: Fri, 26 Aug 2016 16:35:31 +0000
Raw View
--94eb2c112468f47ba5053afc1a2e
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Wed, Aug 24, 2016 at 3:21 PM Nicol Bolas <jmckesson@gmail.com> wrote:
> On Wednesday, August 24, 2016 at 3:16:52 PM UTC-4, Bernd L=C3=B6rwald wro=
te:
>
>>
>> > Am 24.08.2016 um 21:01 schrieb Ville Voutilainen <ville.vo...@gmail.co=
m>:
>>
>> >
>> >> 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
>> >
>> > ..because..?
>>
>> It might sometimes be difficult to express the lifetimes as short as
>> possible:
>>
>> resource a; // begin minimum lifetime a
>> resource b; // begin minimum lifetime b
>> last_use (a); // end minimum lifetime a
>> long_task (b);
>> last_use (b); //end minimum lifetime b
>> // end current lifetime b
>> // end current lifetime a
>>
>>
>
> And how do you know that `b` isn't using `a`?
>
Thanks for pointing out that caveat. I think the solution here is to simply
consider that undefined behavior. That is, when using an "eager"
destructor, it is the programmer's responsibility to ensure that the
objects behave as a scalar, i.e. a self-contained object. A scalar variable
doesn't hold a reference to another variable either (unless it's really
just a reference itself, in which case it's easy to keep track of further
uses and not call the destructor until the last use of either the explicit
reference or the original object).
I'm not entirely sure though what modern compilers do for the above code in
the case where resource is a scalar and a is passed to last_use as a
reference. We wouldn't know if that reference got stored and then used in
the long_task(b) call or last_use(b) call, unless we analyze those
functions. Is that common?
That's the point of Ville's "Define 'last use'." question. You cannot just
> look at code and know that `a` is finished being used when the locally
> visible code stops using it.
>
> Destruction of automatic objects in the reverse order of their
> construction is a guarantee that the standard should not arbitrarily
> discard.
>
I'm certainly not suggesting to discard it arbitrarily. This feature would
have to be opt-in and impose reasonable constraints on how classes with
eager destructors can be used, and have some guarantees of what's safe,
that can be well understood by developers. I'm still exploring what that
means in terms of formal rules, but I'm quite convinced it's possible to
improve on the lazy destruction at the end of a scope, for the use cases
where this matters.
> --
> 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-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/a54b7cf2-6c8=
3-48d5-aeb6-4c179cef1520%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/a54b7cf2-6c=
83-48d5-aeb6-4c179cef1520%40isocpp.org?utm_medium=3Demail&utm_source=3Dfoot=
er>
> .
>
--=20
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 e=
mail 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/CAE7XuEX9HQH7wcgEVD9ywEuNJyGY0gOQwywGU1i4TLXYDOT=
vuQ%40mail.gmail.com.
--94eb2c112468f47ba5053afc1a2e
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 Wed, Aug 24=
, 2016 at 3:21 PM Nicol Bolas <<a href=3D"mailto:jmckesson@gmail.com">jm=
ckesson@gmail.com</a>> wrote:<br></div><blockquote class=3D"gmail_quote"=
style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv dir=3D"ltr">On Wednesday, August 24, 2016 at 3:16:52 PM UTC-4, Bernd L=
=C3=B6rwald wrote:</div><div dir=3D"ltr"><blockquote class=3D"gmail_quote" =
style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left=
:1ex">
<br>> Am 24.08.2016 um 21:01 schrieb Ville Voutilainen <<a rel=3D"nof=
ollow">ville.vo...@gmail.com</a>>:
<br>>=20
<br>>> Limiting the scope with extra braces or by putting the operati=
ons in a
<br>>> subroutine also often isn't a desirable workaround. Note t=
hat compilers have
<br>>=20
<br>> ..because..?
<br>
<br>It might sometimes be difficult to express the lifetimes as short as po=
ssible:
<br>
<br>=C2=A0 resource a; // begin minimum lifetime a
<br>=C2=A0 resource b; // begin minimum lifetime b
<br>=C2=A0 last_use (a); // end minimum lifetime a
<br>=C2=A0 long_task (b);
<br>=C2=A0 last_use (b); //end minimum lifetime b
<br>=C2=A0 // end current lifetime b
<br>=C2=A0 // end current lifetime a
<br>=C2=A0=20
<br></blockquote></div><div dir=3D"ltr"><div><br>And how do you know that `=
b` isn't using `a`?</div></div></blockquote><div><br></div><div>Thanks =
for pointing out that caveat. I think the solution here is to simply consid=
er that undefined behavior. That is, when using an "eager" destru=
ctor, it is the programmer's responsibility to ensure that the objects =
behave as a scalar, i.e. a self-contained object. A scalar variable doesn&#=
39;t hold a reference to another variable either (unless it's really ju=
st a reference itself, in which case it's easy to keep track of further=
uses and not call the destructor until the last use of either the explicit=
reference or the original object).</div><div><br></div><div>I'm not en=
tirely sure though what modern compilers do for the above code in the case =
where=C2=A0<font face=3D"monospace">resource</font> is a scalar and=C2=A0<f=
ont face=3D"monospace">a</font> is passed to <font face=3D"monospace">last_=
use</font> as a reference. We wouldn't know if that reference got store=
d and then used in the <font face=3D"monospace">long_task(b)</font> call or=
<font face=3D"monospace">last_use(b)</font> call, unless we analyze those =
functions. Is that common?</div><div><br></div><blockquote class=3D"gmail_q=
uote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1e=
x"><div dir=3D"ltr"><div>That's the point of=20
Ville's "Define 'last use'." question. You cannot jus=
t look at code and=20
know that `a` is finished being used when the locally visible code stops us=
ing it.<br><br>Destruction of automatic objects in the reverse order of the=
ir construction is a guarantee that the standard should not arbitrarily dis=
card.<br></div></div></blockquote><div><br></div><div>I'm certainly not=
suggesting to discard it arbitrarily. This feature would have to be opt-in=
and impose reasonable constraints on how classes with eager destructors ca=
n be used, and have some guarantees of what's safe, that can be well un=
derstood by developers. I'm still exploring what that means in terms of=
formal rules, but I'm quite convinced it's possible to improve on =
the lazy destruction at the end of a scope, for the use cases where this ma=
tters.</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bo=
rder-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div></di=
v>
<p></p>
-- <br>
You received this message because you are subscribed to a topic in the Goog=
le Groups "ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/IUxA4cx8yHc/unsubscribe" target=3D"_blan=
k">https://groups.google.com/a/isocpp.org/d/topic/std-proposals/IUxA4cx8yHc=
/unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a href=
=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_blank">std-prop=
osals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">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/a54b7cf2-6c83-48d5-aeb6-4c179cef1520%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/a54b7cf2-6c83-=
48d5-aeb6-4c179cef1520%40isocpp.org</a>.<br>
</blockquote></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/CAE7XuEX9HQH7wcgEVD9ywEuNJyGY0gOQwywG=
U1i4TLXYDOTvuQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAE7XuEX9HQH7wcgE=
VD9ywEuNJyGY0gOQwywGU1i4TLXYDOTvuQ%40mail.gmail.com</a>.<br />
--94eb2c112468f47ba5053afc1a2e--
.
Author: Nicolas Capens <nicolas.capens@gmail.com>
Date: Fri, 26 Aug 2016 16:39:42 +0000
Raw View
--94eb2c058454eebabc053afc29a1
Content-Type: text/plain; charset=UTF-8
On Wed, Aug 24, 2016 at 3:53 PM Thiago Macieira <thiago@macieira.org> wrote:
> On quarta-feira, 24 de agosto de 2016 11:51:01 PDT
> nicolas.capens@gmail.com
> wrote:
> > 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.
>
> Locks are the perfect counter-example to what you're proposing. The
> compiler
> simply cannot tell what the "last use" is:
>
> std::lock_guard lock(mutex);
> i = 1;
>
> Where was the last use: before or after the assignment to i?
>
That's not a situation where I would use this feature. See the last example
here
<https://groups.google.com/a/isocpp.org/d/msg/std-proposals/IUxA4cx8yHc/yKNqKl8hDgAJ>
instead. Thank you.
>
> --
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
> Software Architect - Intel Open Source Technology Center
>
> --
> 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-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/5044039.aVzB6kA9Ui%40tjmaciei-mobl1
> .
>
--
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/CAE7XuEX%2BrnYb7dpMhqnFo7ZYi%2BaSo5ivk1QWzC5hTXkT%2BP8Yzg%40mail.gmail.com.
--94eb2c058454eebabc053afc29a1
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Wed=
, Aug 24, 2016 at 3:53 PM Thiago Macieira <<a href=3D"mailto:thiago@maci=
eira.org">thiago@macieira.org</a>> wrote:<br></div><blockquote class=3D"=
gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-=
left:1ex">On quarta-feira, 24 de agosto de 2016 11:51:01 PDT <a href=3D"mai=
lto:nicolas.capens@gmail.com" target=3D"_blank">nicolas.capens@gmail.com</a=
><br>
wrote:<br>
> The use of this would be to free resources held by the object sooner. =
This<br>
> could be heap memory, file handles, mutex locks, etc. Releasing them a=
s<br>
> soon as we're done with the object that represents them would resu=
lt in<br>
> more efficient programs.<br>
<br>
Locks are the perfect counter-example to what you're proposing. The com=
piler<br>
simply cannot tell what the "last use" is:<br>
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 std::lock_guard lock(mutex);<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 i =3D 1;<br>
<br>
Where was the last use: before or after the assignment to i?<br></blockquot=
e><div><br></div><div>That's not a situation where I would use this fea=
ture. See the last example <a href=3D"https://groups.google.com/a/isocpp.or=
g/d/msg/std-proposals/IUxA4cx8yHc/yKNqKl8hDgAJ">here</a> instead. Thank you=
..</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0=
0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
--<br>
Thiago Macieira - thiago (AT) <a href=3D"http://macieira.info" rel=3D"noref=
errer" target=3D"_blank">macieira.info</a> - thiago (AT) <a href=3D"http://=
kde.org" rel=3D"noreferrer" target=3D"_blank">kde.org</a><br>
=C2=A0 =C2=A0Software Architect - Intel Open Source Technology Center<br>
<br>
--<br>
You received this message because you are subscribed to a topic in the Goog=
le Groups "ISO C++ Standard - Future Proposals" 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"noreferr=
er" target=3D"_blank">https://groups.google.com/a/isocpp.org/d/topic/std-pr=
oposals/IUxA4cx8yHc/unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a href=
=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org" target=3D"_blank">std-pr=
oposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">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/5044039.aVzB6kA9Ui%40tjmaciei-mobl1" =
rel=3D"noreferrer" target=3D"_blank">https://groups.google.com/a/isocpp.org=
/d/msgid/std-proposals/5044039.aVzB6kA9Ui%40tjmaciei-mobl1</a>.<br>
</blockquote></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/CAE7XuEX%2BrnYb7dpMhqnFo7ZYi%2BaSo5iv=
k1QWzC5hTXkT%2BP8Yzg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAE7XuEX%2B=
rnYb7dpMhqnFo7ZYi%2BaSo5ivk1QWzC5hTXkT%2BP8Yzg%40mail.gmail.com</a>.<br />
--94eb2c058454eebabc053afc29a1--
.
Author: Nicolas Capens <nicolas.capens@gmail.com>
Date: Fri, 26 Aug 2016 17:05:41 +0000
Raw View
--001a11475786d9a772053afc8625
Content-Type: text/plain; charset=UTF-8
On Wed, Aug 24, 2016 at 4:22 PM Nevin Liber <nevin@eviloverlord.com> wrote:
> On 24 August 2016 at 15:16, <nicolas.capens@gmail.com> wrote:
>
>> The code would become littered with braces if you want to limit the scope
>> of each object to its miminal range,
>>
>
> I don't understand why you would want to do that. Could you elaborate?
>
Certainly. I wrote down three practical use cases here
<https://groups.google.com/a/isocpp.org/forum/#!msg/std-proposals/IUxA4cx8yHc/yKNqKl8hDgAJ>
..
> And if the objects are truly independent and have no observable effect,
> can't a compiler do that under the as-if rule?
>
The problem is that the objects I'm using do have side-effects, so the
compiler won't attempt to shorten their lifespan. But in my use cases the
side effects are "self-contained", i.e. you could treat them as scalars and
destruct them right after their last use.
> Also, if you wish to have a lifetime shorter than a scope for an object of
> type T, you can just use std::optional<T>.
>
How would that work, without requiring manual actions to destruct it?
> Fortunately we don't, because today's compilers do liveness analysis to
>> optimize register allocation.
>>
>
> One of the huge benefits to C++ is that destruction happens at well
> defined times. This would break that.
>
Yes, in many cases it will be preferable to keep the well defined behavior
of implicitly calling the destructor at the end of the variable's scope.
The opt-in feature I'm proposing should be used sparingly and cautiously.
But when used by a well written framework it should be foolproof for the
users of the framework, and offer them significant benefits.
> --
> Nevin ":-)" Liber <mailto:nevin@eviloverlord.com> +1-847-691-1404
>
> --
> 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-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/CAGg_6%2BM3M43y_8jTg4mXce1sz7UQ5kzSkOVqL3F_nYEe-ogzNA%40mail.gmail.com
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAGg_6%2BM3M43y_8jTg4mXce1sz7UQ5kzSkOVqL3F_nYEe-ogzNA%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/CAE7XuEVobd1QW2jJYW-hGTLTPgQxRJM-QkL9jNovOkhaaoXQEw%40mail.gmail.com.
--001a11475786d9a772053afc8625
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Wed=
, Aug 24, 2016 at 4:22 PM Nevin Liber <<a href=3D"mailto:nevin@eviloverl=
ord.com">nevin@eviloverlord.com</a>> wrote:<br></div><blockquote class=
=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr">On 24 August 2016 at 15:16, <span dir=3D"lt=
r"><<a href=3D"mailto:nicolas.capens@gmail.com" target=3D"_blank">nicola=
s.capens@gmail.com</a>></span> wrote:<br></div><div dir=3D"ltr"><div cla=
ss=3D"gmail_extra"><div class=3D"gmail_quote"><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex=
"><div dir=3D"ltr"><div>The code would become littered with braces if you w=
ant to limit the scope of each object to its miminal range,</div></div></bl=
ockquote><div><br></div></div></div></div><div dir=3D"ltr"><div class=3D"gm=
ail_extra"><div class=3D"gmail_quote"><div>I don't understand why you w=
ould want to do that.=C2=A0 Could you elaborate?</div></div></div></div></b=
lockquote><div><br></div><div>Certainly. I wrote down three practical use c=
ases <a href=3D"https://groups.google.com/a/isocpp.org/forum/#!msg/std-prop=
osals/IUxA4cx8yHc/yKNqKl8hDgAJ">here</a>.</div><div>=C2=A0</div><blockquote=
class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc soli=
d;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=
=3D"gmail_quote"><div>And if the objects are truly independent and have no =
observable effect, can't a compiler do that under the as-if rule?</div>=
</div></div></div></blockquote><div><br></div><div>The problem is that the =
objects I'm using do have side-effects, so the compiler won't attem=
pt to shorten their lifespan. But in my use cases the side effects are &quo=
t;self-contained", i.e. you could treat them as scalars and destruct t=
hem right after their last use.</div><div>=C2=A0</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 class=3D"gmail_extra"><div class=3D"gmail_q=
uote"><div>Also, if you wish to have a lifetime shorter than a scope for an=
object of type T, you can just use std::optional<T>.</div></div></di=
v></div></blockquote><div><br></div><div>How would that work, without requi=
ring manual actions to destruct it?</div><div>=C2=A0</div><blockquote class=
=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gma=
il_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bord=
er-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Fortunately =
we don't, because today's compilers do liveness analysis to optimiz=
e register allocation.</div></div></blockquote><div><br></div></div></div><=
/div><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"=
><div>One of the huge benefits to C++ is that destruction happens at well d=
efined times.=C2=A0 This would break that.</div></div></div></div></blockqu=
ote><div><br></div><div>Yes, in many cases it will be preferable to keep th=
e well defined behavior of implicitly calling the destructor at the end of =
the variable's scope. The opt-in feature I'm proposing should be us=
ed sparingly and cautiously. But when used by a well written framework it s=
hould be foolproof for the users of the framework, and offer them significa=
nt benefits.</div><div>=C2=A0</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 class=3D"gmail_extra">-- <br><div data-smartmail=3D"gmail_sig=
nature"><div dir=3D"ltr"><div><div dir=3D"ltr"><div>=C2=A0Nevin ":-)&q=
uot; Liber=C2=A0 <mailto:<a href=3D"mailto:nevin@eviloverlord.com" targe=
t=3D"_blank">nevin@eviloverlord.com</a>> =C2=A0+1-847-691-1404</div></di=
v></div></div></div>
</div></div>
<p></p>
-- <br>
You received this message because you are subscribed to a topic in the Goog=
le Groups "ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/IUxA4cx8yHc/unsubscribe" target=3D"_blan=
k">https://groups.google.com/a/isocpp.org/d/topic/std-proposals/IUxA4cx8yHc=
/unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a href=
=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_blank">std-prop=
osals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">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/CAGg_6%2BM3M43y_8jTg4mXce1sz7UQ5kzSkO=
VqL3F_nYEe-ogzNA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r" target=3D"_blank">https://groups.google.com/a/isocpp.org/d/msgid/std-pro=
posals/CAGg_6%2BM3M43y_8jTg4mXce1sz7UQ5kzSkOVqL3F_nYEe-ogzNA%40mail.gmail.c=
om</a>.<br>
</blockquote></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/CAE7XuEVobd1QW2jJYW-hGTLTPgQxRJM-QkL9=
jNovOkhaaoXQEw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAE7XuEVobd1QW2jJ=
YW-hGTLTPgQxRJM-QkL9jNovOkhaaoXQEw%40mail.gmail.com</a>.<br />
--001a11475786d9a772053afc8625--
.
Author: Ren Industries <renindustries@gmail.com>
Date: Fri, 26 Aug 2016 13:16:24 -0400
Raw View
--94eb2c0658ec9c8507053afcac77
Content-Type: text/plain; charset=UTF-8
Why is it such a terrible imposition to require manual interaction to
enforce this behavior? I don't buy your argument that it is similar to
register allocation; that's a QOI not a standards issue.
On Fri, Aug 26, 2016 at 1:05 PM, Nicolas Capens <nicolas.capens@gmail.com>
wrote:
>
>
> On Wed, Aug 24, 2016 at 4:22 PM Nevin Liber <nevin@eviloverlord.com>
> wrote:
>
>> On 24 August 2016 at 15:16, <nicolas.capens@gmail.com> wrote:
>>
>>> The code would become littered with braces if you want to limit the
>>> scope of each object to its miminal range,
>>>
>>
>> I don't understand why you would want to do that. Could you elaborate?
>>
>
> Certainly. I wrote down three practical use cases here
> <https://groups.google.com/a/isocpp.org/forum/#!msg/std-proposals/IUxA4cx8yHc/yKNqKl8hDgAJ>
> .
>
>
>> And if the objects are truly independent and have no observable effect,
>> can't a compiler do that under the as-if rule?
>>
>
> The problem is that the objects I'm using do have side-effects, so the
> compiler won't attempt to shorten their lifespan. But in my use cases the
> side effects are "self-contained", i.e. you could treat them as scalars and
> destruct them right after their last use.
>
>
>> Also, if you wish to have a lifetime shorter than a scope for an object
>> of type T, you can just use std::optional<T>.
>>
>
> How would that work, without requiring manual actions to destruct it?
>
>
>> Fortunately we don't, because today's compilers do liveness analysis to
>>> optimize register allocation.
>>>
>>
>> One of the huge benefits to C++ is that destruction happens at well
>> defined times. This would break that.
>>
>
> Yes, in many cases it will be preferable to keep the well defined behavior
> of implicitly calling the destructor at the end of the variable's scope.
> The opt-in feature I'm proposing should be used sparingly and cautiously.
> But when used by a well written framework it should be foolproof for the
> users of the framework, and offer them significant benefits.
>
>
>> --
>> Nevin ":-)" Liber <mailto:nevin@eviloverlord.com> +1-847-691-1404
>>
>> --
>> 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-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/CAGg_6%2BM3M43y_
>> 8jTg4mXce1sz7UQ5kzSkOVqL3F_nYEe-ogzNA%40mail.gmail.com
>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAGg_6%2BM3M43y_8jTg4mXce1sz7UQ5kzSkOVqL3F_nYEe-ogzNA%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/CAE7XuEVobd1QW2jJYW-hGTLTPgQxRJM-
> QkL9jNovOkhaaoXQEw%40mail.gmail.com
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAE7XuEVobd1QW2jJYW-hGTLTPgQxRJM-QkL9jNovOkhaaoXQEw%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/CAMD6iD_8zsoqfYdUsY%2BQe_QNvzFsH4c9uUjNYzw5BRFiLQRE%2BQ%40mail.gmail.com.
--94eb2c0658ec9c8507053afcac77
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Why is it such a terrible imposition to require manual int=
eraction to enforce this behavior? I don't buy your argument that it is=
similar to register allocation; that's a QOI not a standards issue.</d=
iv><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">On Fri, Aug 26=
, 2016 at 1:05 PM, Nicolas Capens <span dir=3D"ltr"><<a href=3D"mailto:n=
icolas.capens@gmail.com" target=3D"_blank">nicolas.capens@gmail.com</a>>=
</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .=
8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br><br><=
div class=3D"gmail_quote"><span class=3D""><div dir=3D"ltr">On Wed, Aug 24,=
2016 at 4:22 PM Nevin Liber <<a href=3D"mailto:nevin@eviloverlord.com" =
target=3D"_blank">nevin@eviloverlord.com</a>> wrote:<br></div><blockquot=
e class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc sol=
id;padding-left:1ex"><div dir=3D"ltr">On 24 August 2016 at 15:16, <span di=
r=3D"ltr"><<a href=3D"mailto:nicolas.capens@gmail.com" target=3D"_blank"=
>nicolas.capens@gmail.com</a>></span> wrote:<br></div><div dir=3D"ltr"><=
div class=3D"gmail_extra"><div class=3D"gmail_quote"><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"><div>The code would become littered with braces i=
f you want to limit the scope of each object to its miminal range,</div></d=
iv></blockquote><div><br></div></div></div></div><div dir=3D"ltr"><div clas=
s=3D"gmail_extra"><div class=3D"gmail_quote"><div>I don't understand wh=
y you would want to do that.=C2=A0 Could you elaborate?</div></div></div></=
div></blockquote><div><br></div></span><div>Certainly. I wrote down three p=
ractical use cases <a href=3D"https://groups.google.com/a/isocpp.org/forum/=
#!msg/std-proposals/IUxA4cx8yHc/yKNqKl8hDgAJ" target=3D"_blank">here</a>.</=
div><span class=3D""><div>=C2=A0</div><blockquote class=3D"gmail_quote" sty=
le=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div d=
ir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div>And i=
f the objects are truly independent and have no observable effect, can'=
t a compiler do that under the as-if rule?</div></div></div></div></blockqu=
ote><div><br></div></span><div>The problem is that the objects I'm usin=
g do have side-effects, so the compiler won't attempt to shorten their =
lifespan. But in my use cases the side effects are "self-contained&quo=
t;, i.e. you could treat them as scalars and destruct them right after thei=
r last use.</div><span class=3D""><div>=C2=A0</div><blockquote class=3D"gma=
il_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-lef=
t:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quot=
e"><div>Also, if you wish to have a lifetime shorter than a scope for an ob=
ject of type T, you can just use std::optional<T>.</div></div></div><=
/div></blockquote><div><br></div></span><div>How would that work, without r=
equiring manual actions to destruct it?</div><span class=3D""><div>=C2=A0</=
div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-lef=
t:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_ext=
ra"><div class=3D"gmail_quote"><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>Fortunately we don't, because today's compilers do livenes=
s analysis to optimize register allocation.</div></div></blockquote><div><b=
r></div></div></div></div><div dir=3D"ltr"><div class=3D"gmail_extra"><div =
class=3D"gmail_quote"><div>One of the huge benefits to C++ is that destruct=
ion happens at well defined times.=C2=A0 This would break that.</div></div>=
</div></div></blockquote><div><br></div></span><div>Yes, in many cases it w=
ill be preferable to keep the well defined behavior of implicitly calling t=
he destructor at the end of the variable's scope. The opt-in feature I&=
#39;m proposing should be used sparingly and cautiously. But when used by a=
well written framework it should be foolproof for the users of the framewo=
rk, and offer them significant benefits.</div><div>=C2=A0</div><blockquote =
class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid=
;padding-left:1ex"><span class=3D""><div dir=3D"ltr"><div class=3D"gmail_ex=
tra">-- <br><div data-smartmail=3D"gmail_signature"><div dir=3D"ltr"><div><=
div dir=3D"ltr"><div>=C2=A0Nevin ":-)" Liber=C2=A0 <mailto:<a =
href=3D"mailto:nevin@eviloverlord.com" target=3D"_blank">nevin@eviloverlord=
..com</a><wbr>> =C2=A0<a href=3D"tel:%2B1-847-691-1404" value=3D"+1847691=
1404" target=3D"_blank">+1-847-691-1404</a></div></div></div></div></div>
</div></div>
<p></p>
-- <br></span>
You received this message because you are subscribed to a topic in the Goog=
le Groups "ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/IUxA4cx8yHc/unsubscribe" target=3D"_blan=
k">https://groups.google.com/a/<wbr>isocpp.org/d/topic/std-<wbr>proposals/I=
UxA4cx8yHc/<wbr>unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a href=
=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_blank">std-prop=
osals+unsubscribe@<wbr>isocpp.org</a>.<span class=3D""><br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">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/CAGg_6%2BM3M43y_8jTg4mXce1sz7UQ5kzSkO=
VqL3F_nYEe-ogzNA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r" target=3D"_blank">https://groups.google.com/a/<wbr>isocpp.org/d/msgid/st=
d-<wbr>proposals/CAGg_6%2BM3M43y_<wbr>8jTg4mXce1sz7UQ5kzSkOVqL3F_<wbr>nYEe-=
ogzNA%40mail.gmail.com</a>.<br>
</span></blockquote></div></div><span class=3D"">
<p></p>
-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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" target=3D"_=
blank">std-proposals+unsubscribe@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></span>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAE7XuEVobd1QW2jJYW-hGTLTPgQxRJM-QkL9=
jNovOkhaaoXQEw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
target=3D"_blank">https://groups.google.com/a/<wbr>isocpp.org/d/msgid/std-=
<wbr>proposals/CAE7XuEVobd1QW2jJYW-<wbr>hGTLTPgQxRJM-<wbr>QkL9jNovOkhaaoXQE=
w%40mail.<wbr>gmail.com</a>.<br>
</blockquote></div><br></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/CAMD6iD_8zsoqfYdUsY%2BQe_QNvzFsH4c9uU=
jNYzw5BRFiLQRE%2BQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAMD6iD_8zsoq=
fYdUsY%2BQe_QNvzFsH4c9uUjNYzw5BRFiLQRE%2BQ%40mail.gmail.com</a>.<br />
--94eb2c0658ec9c8507053afcac77--
.
Author: Nicolas Capens <nicolas.capens@gmail.com>
Date: Fri, 26 Aug 2016 17:51:39 +0000
Raw View
--001a1147b804370de4053afd2b33
Content-Type: text/plain; charset=UTF-8
On Wed, Aug 24, 2016 at 5:31 PM <inkwizytoryankes@gmail.com> wrote:
>
>
> On Wednesday, August 24, 2016 at 10:16:30 PM UTC+2, nicolas...@gmail.com
> wrote:
>>
>> On Wednesday, August 24, 2016 at 3:01:34 PM UTC-4, Ville Voutilainen
>> wrote:
>>>
>>> On 24 August 2016 at 21:51, <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.
>>>
>>> Define "last use".
>>>
>>
>> The last use according to liveness analysis.
>>
>>
>
> I have 4 functions:
> int main()
> {
> resource a;
> funcA(&a);
> funcB();
> funcC();
> funcD();
> }
> What function `funcA` do with `a`? What if it store reference to `a` for
> future use (or reference to any part of it)? What if `funcB` or `funcD` use
> this reference too? `a` could be used in other thread (`funcA` ===
> `startThread` and `funcD` === `joinThread`).
> Compiler can't know that. Even more, this functions could not exists in
> exe at all and be from run time dll.
>
Yes, that's a very good example of where "last use" is not trivial. But
let's again turn toward liveness analysis of scalars. If the compiler can
determine that funcA does not store a reference to a, then it can safely
free up its register after this call, or, in the case of an object, call
its constructor when we indicate that we want this behavior. I assume most
compilers would be capable of that? If not, it still seems reasonable to me
to spec this eager destruction to be conservative, and in the worst case to
result in destruction at the end of the scope.
If funcA is in another module and one of the other functions is also from
that same module then the conservative behavior would also be to not call
the destructor eagerly. But perhaps we could make an exception here. After
all it is very poor API design to hold a reference to a local variable. It
could easily have been destroyed just by going out of scope. I don't know
of any legitimate uses of that.
Perhaps we can even reasonably make that assumption for functions within
the same module. That is, make it undefined behavior or even invalid to
store a reference to an eagerly destructed object outside of local
variables. It would relieve the compiler from having to inspect functions
(if that's an unreasonable thing to do, which I'm not convinced it is).
--
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/CAE7XuEW8HZtTHPJACq2%3D7JFrVBVgGt7YSqaHwc_McZrRRv1-ww%40mail.gmail.com.
--001a1147b804370de4053afd2b33
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 Wed, Aug 24=
, 2016 at 5:31 PM <<a href=3D"mailto:inkwizytoryankes@gmail.com">inkwizy=
toryankes@gmail.com</a>> wrote:<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"><br><br>On Wednesday, August 24, 2016 at 10:16:30 PM UTC+2=
, <a href=3D"mailto:nicolas...@gmail.com" target=3D"_blank">nicolas...@gmai=
l.com</a> 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">On=
Wednesday, August 24, 2016 at 3:01:34 PM UTC-4, Ville Voutilainen wrote:<b=
lockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-=
left:1px #ccc solid;padding-left:1ex">On 24 August 2016 at 21:51, =C2=A0<=
;<a rel=3D"nofollow">nicolas...@gmail.com</a>> wrote:
<br>> Hi all,
<br>>
<br>> I'd like to propose a new kind of destructor that gets called =
after a local
<br>> object's last use, instead of at the end of its scope.
<br>
<br>Define "last use".
<br></blockquote><div><br></div><div>The last use according to liveness ana=
lysis.</div><div>=C2=A0</div></div></blockquote></div><div dir=3D"ltr"><div=
><br>I have 4 functions:<br><div style=3D"background-color:rgb(250,250,250)=
;border-color:rgb(187,187,187);border-style:solid;border-width:1px;word-wra=
p:break-word"><code><div><span style=3D"color:#008">int</span><span style=
=3D"color:#000"> main</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>=C2=A0 =C2=A0 resource a</span><span style=3D"color:#66=
0">;</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 funcA</span><span s=
tyle=3D"color:#660">(&</span><span style=3D"color:#000">a</span><span s=
tyle=3D"color:#660">);</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 f=
uncB</span><span style=3D"color:#660">();</span><span style=3D"color:#000">=
<br>=C2=A0 =C2=A0 funcC</span><span style=3D"color:#660">();</span><span st=
yle=3D"color:#000"><br>=C2=A0 =C2=A0 funcD</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></span></div></code></div>What func=
tion `funcA` do with `a`? What if it store reference to `a` for future use =
(or reference to any part of it)? What if `funcB` or `funcD` use this refer=
ence too? `a` could be used in other thread (`funcA` =3D=3D=3D `startThread=
` and `funcD` =3D=3D=3D `joinThread`).<br>Compiler can't know that. Eve=
n more, this functions could not exists in exe at all and be from run time =
dll.<br></div></div></blockquote><div><br></div><div>Yes, that's a very=
good example of where "last use" is not trivial. But let's a=
gain turn toward liveness analysis of scalars. If the compiler can determin=
e that <font face=3D"monospace">funcA</font> does not store a reference to =
<font face=3D"monospace">a</font>, then it can safely free up its register =
after this call, or, in the case of an object, call its constructor when we=
indicate that we want this behavior. I assume most compilers would be capa=
ble of that? If not, it still seems reasonable to me to spec this eager des=
truction to be conservative, and in the worst case to result in destruction=
at the end of the scope.</div><div><br></div><div>If <font face=3D"monospa=
ce">funcA</font> is in another module and one of the other functions is als=
o from that same module then the conservative behavior would also be to not=
call the destructor eagerly. But perhaps we could make an exception here. =
After all it is very poor API design to hold a reference to a local variabl=
e. It could easily have been destroyed just by going out of scope. I don=
9;t know of any legitimate uses of that.</div><div><br></div><div>Perhaps w=
e can even reasonably make that assumption for functions within the same mo=
dule. That is, make it undefined behavior or even invalid to store a refere=
nce to an eagerly destructed object outside of local variables. It would re=
lieve the compiler from having to inspect functions (if that's an unrea=
sonable thing to do, which I'm not convinced it is).</div></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/CAE7XuEW8HZtTHPJACq2%3D7JFrVBVgGt7YSq=
aHwc_McZrRRv1-ww%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAE7XuEW8HZtTHP=
JACq2%3D7JFrVBVgGt7YSqaHwc_McZrRRv1-ww%40mail.gmail.com</a>.<br />
--001a1147b804370de4053afd2b33--
.
Author: Nicolas Capens <nicolas.capens@gmail.com>
Date: Fri, 26 Aug 2016 15:21:37 -0400
Raw View
--001a114c8bbe8dce37053afe6ce4
Content-Type: text/plain; charset=UTF-8
On Fri, Aug 26, 2016 at 1:16 PM, Ren Industries <renindustries@gmail.com>
wrote:
> Why is it such a terrible imposition to require manual interaction to
> enforce this behavior? I don't buy your argument that it is similar to
> register allocation; that's a QOI not a standards issue.
>
Consider this simple statement:
x = a * b * c;
Assume they're all scalars, and a, b, and c are no longer used after this
statement. That means liveness analysis will make their registers available
for other variables, without you having to worry about it. But if instead
these variables were huge matrices and you had to manually free their
storage to minimize memory consumption, then it would look something like
this:
Matrix t = a * b;
a.~Matrix();
b.~Matrix();
x = t * c;
t.~Matrix();
c.~Matrix();
Or if you wanted to do it with scopes:
{
Matrix t;
{
Matrix a = ...;
Matrix b = ...;
t = a * b;
}
Matrix c = ...;
x = t * c;
}
To me the original statement looks a whole lot easier to read and maintain
than the two workarounds. And this is just a trivial example! It would
become insane to do it for any realistic data processing code.
Also I think that calling something a "terrible imposition" or not is
highly subjective. Many recent C++ features solve issues that already had
workarounds which some considered acceptable but were unworkable for
others. So please avoid being prejudiced by your own experience and having
no direct use for this yourself. C++ supports a huge variety of
applications.
I hope the above example illustrates that this is very similar to register
allocation, and it's a standards issue that we don't get this behavior
today for non-scalar types.
> On Fri, Aug 26, 2016 at 1:05 PM, Nicolas Capens <nicolas.capens@gmail.com>
> wrote:
>
>>
>>
>> On Wed, Aug 24, 2016 at 4:22 PM Nevin Liber <nevin@eviloverlord.com>
>> wrote:
>>
>>> On 24 August 2016 at 15:16, <nicolas.capens@gmail.com> wrote:
>>>
>>>> The code would become littered with braces if you want to limit the
>>>> scope of each object to its miminal range,
>>>>
>>>
>>> I don't understand why you would want to do that. Could you elaborate?
>>>
>>
>> Certainly. I wrote down three practical use cases here
>> <https://groups.google.com/a/isocpp.org/forum/#!msg/std-proposals/IUxA4cx8yHc/yKNqKl8hDgAJ>
>> .
>>
>>
>>> And if the objects are truly independent and have no observable effect,
>>> can't a compiler do that under the as-if rule?
>>>
>>
>> The problem is that the objects I'm using do have side-effects, so the
>> compiler won't attempt to shorten their lifespan. But in my use cases the
>> side effects are "self-contained", i.e. you could treat them as scalars and
>> destruct them right after their last use.
>>
>>
>>> Also, if you wish to have a lifetime shorter than a scope for an object
>>> of type T, you can just use std::optional<T>.
>>>
>>
>> How would that work, without requiring manual actions to destruct it?
>>
>>
>>> Fortunately we don't, because today's compilers do liveness analysis to
>>>> optimize register allocation.
>>>>
>>>
>>> One of the huge benefits to C++ is that destruction happens at well
>>> defined times. This would break that.
>>>
>>
>> Yes, in many cases it will be preferable to keep the well defined
>> behavior of implicitly calling the destructor at the end of the variable's
>> scope. The opt-in feature I'm proposing should be used sparingly and
>> cautiously. But when used by a well written framework it should be
>> foolproof for the users of the framework, and offer them significant
>> benefits.
>>
>>
>>> --
>>> Nevin ":-)" Liber <mailto:nevin@eviloverlord.com> +1-847-691-1404
>>>
>>> --
>>> 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/is
>>> ocpp.org/d/topic/std-proposals/IUxA4cx8yHc/unsubscribe.
>>> To unsubscribe from this group and all its topics, 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/is
>>> ocpp.org/d/msgid/std-proposals/CAGg_6%2BM3M43y_8jTg4mXce1sz7
>>> UQ5kzSkOVqL3F_nYEe-ogzNA%40mail.gmail.com
>>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAGg_6%2BM3M43y_8jTg4mXce1sz7UQ5kzSkOVqL3F_nYEe-ogzNA%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/is
>> ocpp.org/d/msgid/std-proposals/CAE7XuEVobd1QW2jJYW-hGTLTPgQx
>> RJM-QkL9jNovOkhaaoXQEw%40mail.gmail.com
>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAE7XuEVobd1QW2jJYW-hGTLTPgQxRJM-QkL9jNovOkhaaoXQEw%40mail.gmail.com?utm_medium=email&utm_source=footer>
>> .
>>
>
> --
> 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-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/CAMD6iD_8zsoqfYdUsY%2BQe_
> QNvzFsH4c9uUjNYzw5BRFiLQRE%2BQ%40mail.gmail.com
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAMD6iD_8zsoqfYdUsY%2BQe_QNvzFsH4c9uUjNYzw5BRFiLQRE%2BQ%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/CAE7XuEWHUHdPz5LyLf%2BMxU5NaPOMMhLcjofvHhdYJK1z2Qvt_g%40mail.gmail.com.
--001a114c8bbe8dce37053afe6ce4
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On F=
ri, Aug 26, 2016 at 1:16 PM, Ren Industries <span dir=3D"ltr"><<a href=
=3D"mailto:renindustries@gmail.com" target=3D"_blank">renindustries@gmail.c=
om</a>></span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"marg=
in:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1e=
x"><div dir=3D"ltr">Why is it such a terrible imposition to require manual =
interaction to enforce this behavior? I don't buy your argument that it=
is similar to register allocation; that's a QOI not a standards issue.=
</div></blockquote><div><br></div><div>Consider this simple statement:</div=
><div><br></div><div>=C2=A0 =C2=A0 x =3D a * b * c;</div><div><br></div><di=
v>Assume they're all scalars, and a, b, and c are no longer used after =
this statement. That means liveness analysis will make their registers avai=
lable for other variables, without you having to worry about it. But if ins=
tead these variables were huge matrices and you had to manually free their =
storage to minimize memory consumption, then it would look something like t=
his:</div><div><br></div><div>=C2=A0 =C2=A0 Matrix t =3D a * b;</div><div>=
=C2=A0 =C2=A0 a.~Matrix();</div><div>=C2=A0 =C2=A0 b.~Matrix();</div><div>=
=C2=A0 =C2=A0 x =3D t * c;</div><div>=C2=A0 =C2=A0 t.~Matrix();</div><div>=
=C2=A0 =C2=A0 c.~Matrix();</div><div><br></div><div>Or if you wanted to do =
it with scopes:</div><div><br></div><div>=C2=A0 =C2=A0 {</div><div>=C2=A0 =
=C2=A0 Matrix t;</div><div>=C2=A0 =C2=A0 {</div><div>=C2=A0 =C2=A0 Matrix a=
=3D ...;</div><div>=C2=A0 =C2=A0 Matrix b =3D ...;</div><div>=C2=A0 =C2=A0=
t =3D a * b;</div><div>=C2=A0 =C2=A0 }</div><div>=C2=A0 =C2=A0 Matrix c =
=3D ...;<br></div><div>=C2=A0 =C2=A0 x =3D t * c;</div><div>=C2=A0 =C2=A0 }=
</div><div><br></div><div>To me the original statement looks a whole lot ea=
sier to read and maintain than the two workarounds. And this is just a triv=
ial example! It would become insane to do it for any realistic data process=
ing code.</div><div><br></div><div>Also I think that calling something a &q=
uot;terrible imposition" or not is highly subjective. Many recent C++ =
features solve issues that already had workarounds which some considered ac=
ceptable but were unworkable for others. So please avoid being prejudiced b=
y your own experience and having no direct use for this yourself. C++ suppo=
rts a huge variety of applications.</div><div><br></div><div>I hope the abo=
ve example illustrates that this is very similar to register allocation, an=
d it's a standards issue that we don't get this behavior today for =
non-scalar types.</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);pad=
ding-left:1ex"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div><=
div class=3D"h5">On Fri, Aug 26, 2016 at 1:05 PM, Nicolas Capens <span dir=
=3D"ltr"><<a href=3D"mailto:nicolas.capens@gmail.com" target=3D"_blank">=
nicolas.capens@gmail.com</a>></span> wrote:<br></div></div><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px soli=
d rgb(204,204,204);padding-left:1ex"><div><div class=3D"h5"><div dir=3D"ltr=
"><br><br><div class=3D"gmail_quote"><span><div dir=3D"ltr">On Wed, Aug 24,=
2016 at 4:22 PM Nevin Liber <<a href=3D"mailto:nevin@eviloverlord.com" =
target=3D"_blank">nevin@eviloverlord.com</a>> wrote:<br></div><blockquot=
e class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px s=
olid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr">On 24 August 2016 =
at 15:16, <span dir=3D"ltr"><<a href=3D"mailto:nicolas.capens@gmail.com=
" target=3D"_blank">nicolas.capens@gmail.com</a>></span> wrote:<br></div=
><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-lef=
t:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>The co=
de would become littered with braces if you want to limit the scope of each=
object to its miminal range,</div></div></blockquote><div><br></div></div>=
</div></div><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail=
_quote"><div>I don't understand why you would want to do that.=C2=A0 Co=
uld you elaborate?</div></div></div></div></blockquote><div><br></div></spa=
n><div>Certainly. I wrote down three practical use cases <a href=3D"https:/=
/groups.google.com/a/isocpp.org/forum/#!msg/std-proposals/IUxA4cx8yHc/yKNqK=
l8hDgAJ" target=3D"_blank">here</a>.</div><span><div>=C2=A0</div><blockquot=
e class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px s=
olid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmai=
l_extra"><div class=3D"gmail_quote"><div>And if the objects are truly indep=
endent and have no observable effect, can't a compiler do that under th=
e as-if rule?</div></div></div></div></blockquote><div><br></div></span><di=
v>The problem is that the objects I'm using do have side-effects, so th=
e compiler won't attempt to shorten their lifespan. But in my use cases=
the side effects are "self-contained", i.e. you could treat them=
as scalars and destruct them right after their last use.</div><span><div>=
=C2=A0</div><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"l=
tr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div>Also, if you=
wish to have a lifetime shorter than a scope for an object of type T, you =
can just use std::optional<T>.</div></div></div></div></blockquote><d=
iv><br></div></span><div>How would that work, without requiring manual acti=
ons to destruct it?</div><span><div>=C2=A0</div><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 class=3D"gmail_extra"><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"><div d=
ir=3D"ltr"><div>Fortunately we don't, because today's compilers do =
liveness analysis to optimize register allocation.</div></div></blockquote>=
<div><br></div></div></div></div><div dir=3D"ltr"><div class=3D"gmail_extra=
"><div class=3D"gmail_quote"><div>One of the huge benefits to C++ is that d=
estruction happens at well defined times.=C2=A0 This would break that.</div=
></div></div></div></blockquote><div><br></div></span><div>Yes, in many cas=
es it will be preferable to keep the well defined behavior of implicitly ca=
lling the destructor at the end of the variable's scope. The opt-in fea=
ture I'm proposing should be used sparingly and cautiously. But when us=
ed by a well written framework it should be foolproof for the users of the =
framework, and offer them significant benefits.</div><div>=C2=A0</div><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:=
1px solid rgb(204,204,204);padding-left:1ex"><span><div dir=3D"ltr"><div cl=
ass=3D"gmail_extra">-- <br><div data-smartmail=3D"gmail_signature"><div dir=
=3D"ltr"><div><div dir=3D"ltr"><div>=C2=A0Nevin ":-)" Liber=C2=A0=
<mailto:<a href=3D"mailto:nevin@eviloverlord.com" target=3D"_blank">nev=
in@eviloverlord.com</a><wbr>> =C2=A0<a href=3D"tel:%2B1-847-691-1404" va=
lue=3D"+18476911404" target=3D"_blank">+1-847-691-1404</a></div></div></div=
></div></div>
</div></div>
<p></p>
-- <br></span>
You received this message because you are subscribed to a topic in the Goog=
le Groups "ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/IUxA4cx8yHc/unsubscribe" target=3D"_blan=
k">https://groups.google.com/a/is<wbr>ocpp.org/d/topic/std-proposals<wbr>/I=
UxA4cx8yHc/unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a href=
=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_blank">std-prop=
osals+unsubscribe@isoc<wbr>pp.org</a>.<span><br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">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/CAGg_6%2BM3M43y_8jTg4mXce1sz7UQ5kzSkO=
VqL3F_nYEe-ogzNA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r" target=3D"_blank">https://groups.google.com/a/is<wbr>ocpp.org/d/msgid/st=
d-proposals<wbr>/CAGg_6%2BM3M43y_8jTg4mXce1sz7<wbr>UQ5kzSkOVqL3F_nYEe-ogzNA=
%<wbr>40mail.gmail.com</a>.<br>
</span></blockquote></div></div></div></div><span>
<p></p>
-- <br><span class=3D"">
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br></span>
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" target=3D"_=
blank">std-proposals+unsubscribe@isoc<wbr>pp.org</a>.<span class=3D""><br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></span></span>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAE7XuEVobd1QW2jJYW-hGTLTPgQxRJM-QkL9=
jNovOkhaaoXQEw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
target=3D"_blank">https://groups.google.com/a/is<wbr>ocpp.org/d/msgid/std-=
proposals<wbr>/CAE7XuEVobd1QW2jJYW-hGTLTPgQx<wbr>RJM-QkL9jNovOkhaaoXQEw%40m=
ail.<wbr>gmail.com</a>.<br>
</blockquote></div><br></div><span class=3D"">
<p></p>
-- <br>
You received this message because you are subscribed to a topic in the Goog=
le Groups "ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/IUxA4cx8yHc/unsubscribe" target=3D"_blan=
k">https://groups.google.com/a/<wbr>isocpp.org/d/topic/std-<wbr>proposals/I=
UxA4cx8yHc/<wbr>unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a href=
=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_blank">std-prop=
osals+unsubscribe@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></span>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAMD6iD_8zsoqfYdUsY%2BQe_QNvzFsH4c9uU=
jNYzw5BRFiLQRE%2BQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoo=
ter" target=3D"_blank">https://groups.google.com/a/<wbr>isocpp.org/d/msgid/=
std-<wbr>proposals/CAMD6iD_8zsoqfYdUsY%<wbr>2BQe_<wbr>QNvzFsH4c9uUjNYzw5BRF=
iLQRE%<wbr>2BQ%40mail.gmail.com</a>.<br>
</blockquote></div><br></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/CAE7XuEWHUHdPz5LyLf%2BMxU5NaPOMMhLcjo=
fvHhdYJK1z2Qvt_g%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAE7XuEWHUHdPz5=
LyLf%2BMxU5NaPOMMhLcjofvHhdYJK1z2Qvt_g%40mail.gmail.com</a>.<br />
--001a114c8bbe8dce37053afe6ce4--
.
Author: Nicolas Capens <nicolas.capens@gmail.com>
Date: Fri, 26 Aug 2016 15:34:43 -0400
Raw View
--94eb2c112468426f33053afe9ba1
Content-Type: text/plain; charset=UTF-8
On Wed, Aug 24, 2016 at 5:43 PM, Magnus Fromreide <magfr@lysator.liu.se>
wrote:
> On Wed, Aug 24, 2016 at 11:51:01AM -0700, nicolas.capens@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();".
>
> This do sound like you are expecting the normal destructor to get called at
> end of scope, is this correct?
>
No, I envisioned that there would just be one implicit call to the
destructor, which is either a classic "lazy" one or the newly proposed
"eager" one. The only thing that changes is the point where it gets called.
So the default is still at the end of the scope, but when opting in to
eager destruction it would get called after the last use of the object
(with some unresolved wiggle room for the definition of last use).
That said, it's worth entertaining the idea of having both kinds of
destructor! Perhaps some objects can have some of their content destructed
eagerly while other bits need to stick around until the end of the scope. I
can't immediately think of an example, but that doesn't have to stop us
from enabling this scenario too. Thanks!
> If so then what would this extra destructor do that
>
> T(std::move(aT));
>
> doesn't do today?
>
I need the eager destructor to be called automatically, not manually, to
keep the code more readable.
> /MF
>
> --
> 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-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/20160824214337.GA18752%40noemi.
>
--
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/CAE7XuEVh4obh69JwLBOo7qgaRA5iu%2BHx87L9uv1eaGVSZvqPDA%40mail.gmail.com.
--94eb2c112468426f33053afe9ba1
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><div class=3D"gmail_quo=
te">On Wed, Aug 24, 2016 at 5:43 PM, Magnus Fromreide <span dir=3D"ltr"><=
;<a href=3D"mailto:magfr@lysator.liu.se" target=3D"_blank">magfr@lysator.li=
u.se</a>></span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=3D=
"">On Wed, Aug 24, 2016 at 11:51:01AM -0700, <a href=3D"mailto:nicolas.cape=
ns@gmail.com">nicolas.capens@gmail.com</a> wrote:<br>
> Hi all,<br>
><br>
> I'd like to propose a new kind of destructor that gets called afte=
r a local<br>
> object's last use, instead of at the end of its scope.<br>
><br>
> The use of this would be to free resources held by the object sooner. =
This<br>
> could be heap memory, file handles, mutex locks, etc. Releasing them a=
s<br>
> soon as we're done with the object that represents them would resu=
lt in<br>
> more efficient programs.<br>
><br>
> Currently such optimization can only be achieved by explicitly releasi=
ng<br>
> the resources, which is inconvenient, bug prone, and reduces readabili=
ty.<br>
> Limiting the scope with extra braces or by putting the operations in a=
<br>
> subroutine also often isn't a desirable workaround. Note that comp=
ilers<br>
> have been doing liveness analysis for register allocation and stack<br=
>
> compaction for a very long time and we take these optimizations for<br=
>
> granted. I'd like to see it get extended to heap memory and other =
resources<br>
> as well.<br>
><br>
> The syntax for this could be an annotation of the destructor declarati=
on<br>
> with a keyword, symbol, or attribute. For example, "auto ~Object(=
);",<br>
> "volatile ~Object();", "~~Object();", or "[[e=
ager]] ~Object();".<br>
<br>
</span>This do sound like you are expecting the normal destructor to get ca=
lled at<br>
end of scope, is this correct?<br></blockquote><div><br></div><div>No, I en=
visioned that there would just be one implicit call to the destructor, whic=
h is either a classic "lazy" one or the newly proposed "eage=
r" one. The only thing that changes is the point where it gets called.=
So the default is still at the end of the scope, but when opting in to eag=
er destruction it would get called after the last use of the object (with s=
ome unresolved wiggle room for the definition of last use).</div><div><br><=
/div><div>That said, it's worth entertaining the idea of having both ki=
nds of destructor! Perhaps some objects can have some of their content dest=
ructed eagerly while other bits need to stick around until the end of the s=
cope. I can't immediately think of an example, but that doesn't hav=
e to stop us from enabling this scenario too. Thanks!</div><div>=C2=A0</div=
><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1=
px #ccc solid;padding-left:1ex">
If so then what would this extra destructor do that<br>
<br>
T(std::move(aT));<br>
<br>
doesn't do today?<br></blockquote><div><br></div><div>I need the eager =
destructor to be called automatically, not manually, to keep the code more =
readable.</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"=
margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
/MF<br>
<span class=3D""><br>
--<br>
You received this message because you are subscribed to a topic in the Goog=
le Groups "ISO C++ Standard - Future Proposals" 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"noreferr=
er" target=3D"_blank">https://groups.google.com/a/<wbr>isocpp.org/d/topic/s=
td-<wbr>proposals/IUxA4cx8yHc/<wbr>unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a href=
=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org">std-proposals+unsubscrib=
e@<wbr>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>
</span>To view this discussion on the web visit <a href=3D"https://groups.g=
oogle.com/a/isocpp.org/d/msgid/std-proposals/20160824214337.GA18752%40noemi=
" rel=3D"noreferrer" target=3D"_blank">https://groups.google.com/a/<wbr>iso=
cpp.org/d/msgid/std-<wbr>proposals/20160824214337.<wbr>GA18752%40noemi</a>.=
<br>
</blockquote></div><br></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/CAE7XuEVh4obh69JwLBOo7qgaRA5iu%2BHx87=
L9uv1eaGVSZvqPDA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAE7XuEVh4obh69=
JwLBOo7qgaRA5iu%2BHx87L9uv1eaGVSZvqPDA%40mail.gmail.com</a>.<br />
--94eb2c112468426f33053afe9ba1--
.
Author: Nicolas Capens <nicolas.capens@gmail.com>
Date: Fri, 26 Aug 2016 17:23:51 -0400
Raw View
--001a114c8bbe890069053b0021e7
Content-Type: text/plain; charset=UTF-8
On Wed, Aug 24, 2016 at 6:00 PM, Matt Calabrese <calabrese@x.team> wrote:
> On Wed, Aug 24, 2016 at 2:17 PM, <nicolas.capens@gmail.com> wrote:
>
>> On Wednesday, August 24, 2016 at 3:19:24 PM UTC-4, Matt Calabrese wrote:
>>>
>>> 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.
>>
>
> Again, the problem is that "last use" isn't something that can actually be
> determined in any meaningful sense. For this to be usable, the *user* needs
> to notate their last use by explicitly calling some kind of special
> destructive operation that doesn't currently exist in the language (a
> hypothetical destructive move operation would be one of those special kinds
> of operations). I and others have given you examples of why what you want
> cannot be done truly automatically in a language like C++.
>
I'm sorry but that's simply not true. For all of the examples
<https://groups.google.com/a/isocpp.org/forum/#!msg/std-proposals/IUxA4cx8yHc/yKNqKl8hDgAJ>
that I provided, it would suffice to call the destructor after the last
*local* use of the variable. The only issue with that is that there's a
number of ways in which non-local uses can lead to crashes and whatnot. So
it's worth exploring if we can improve on the trivial specification, but if
not, it would still be helpful to have.
Let's not forget that destruction at the end of the scope is not foolproof
either:
int *p;
{
int i;
p = &i;
}
*p = 0; // Yikes!
And this can happen in very subtle ways:
{
int i;
foo(i);
}
bar();
foo() could be taking i's address and bar could try to dereference it.
All I'm saying is let's not pretend that destruction at end of scope solves
the last use issue in the absolute sense. It's a compromise, that happens
to be well understood. So we don't have to shoot for the stars for eager
destruction either. Destruction at the last local use seems like a workable
starting point to me.
> On Wed, Aug 24, 2016 at 2:17 PM, <nicolas.capens@gmail.com> wrote:
>
>> 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.
>>
>
> There is no way in practice to implicitly know when an object is okay to
> be disposed of without the user providing such information.
>
> On Wed, Aug 24, 2016 at 2:17 PM, <nicolas.capens@gmail.com> wrote:
>
>> Anyway, for the use cases that I envision, the annotation at destructor
>> declaration is appropriate. For example say I need a huge matrix to
>> temporarily store some intermediate results. I could use "double
>> matrix[10000][10000];" and rely on the compiler's optimizations to use the
>> memory for other purposes as soon as I'm done with this matrix. But it's
>> simply not going to fit on the stack. So instead I'll use an object with a
>> pointer to heap memory. But now it only gets freed when it goes out of
>> scope. 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.
>>
>
> Before again going into the subtleties of why annotation strictly at the
> type level won't work, just think about what you've said -- the user would
> have to use an equivalent type without eager destruction if they didn't
> want this behavior. So now you have two types that do exactly the same
> thing but one with an "eager" destructor?
>
No, not really. All practical use cases of a Matrix class could use eager
destruction. A well written support library for it would avoid storing
references that could lead to another use after it was destructed eagerly
after the last use in the scope where the object was defined.
Also keep in mind that you can still take explicit control over its
lifetime using new/delete. I'm only proposing an alternative implicit
lifetime for local variables.
I only mentioned the possibility of having two kinds of classes with
different destructor behavior for cases like a mutex lock. Some locks make
good use of the destruction at end of scope behavior, while others
<https://groups.google.com/a/isocpp.org/forum/#!msg/std-proposals/IUxA4cx8yHc/yKNqKl8hDgAJ>
would benefit from releasing sooner. For well designed classes it should be
intuitive. And there shouldn't be two otherwise identical classes with
different destructor behavior that you'd use at the same time. Perhaps I
shouldn't have used the word "equivalent" before. I merely meant that in
the sense of for example a different matrix library which does store
references for later use, and so the designer of the library can decide not
to use eager destruction.
It doesn't seem useful to me to specify it on a per-object basis. It would
be much harder to use than a framework which was designed from the ground
up to only use eager destruction on certain types. Not to mention the
syntax for this would probably be cumbersome and distracting. Anyway, feel
free to give me a counter-example where it's not reasonable to choose
between lazy or eager destruction at the type declaration and have a
library built for it with that choice in mind.
> As I'll reiterate, the user effectively needs to somehow notate at the
> usage point where they are done with the object, but even if you don't get
> that argument, certainly your desire for two equivalent types should hint
> to you that someone would at least want to put the notation at the point of
> declaration of the *object* that they want "eagerly" disposed of, instead
> of having it be a part of the type. This removes the need for multiple
> types that you describe.
>
> Anyway, apart from that, another simple example of where this breaks down:
> you have your matrix type that you've described and some accessor taking a
> row index and a column index. This function returns a reference to an
> element of that matrix. Someone uses the function to access an element.
> When is your matrix ready for disposal? Nobody is 'touching" your matrix
> type immediately after you call that function, but a reference to one of
> its elements still exists. Strictly speaking, the matrix could be "eagerly"
> destroyed as soon as the accessor function returns, before the element is
> even truly accessed through the reference. Even if you delay your disposal
> until the end of the full expression, what happens if the reference is
> stored and accessed in the next statement? This is not at all an
> unreasonable scenario. Do you expect to track such references? If so, why
> -- how would the compiler know which references to track. Is the compiler
> expected to know that the reference which is returned corresponds to
> something that is owned by the object that was accessed as opposed to just
> a reference to some other, longer-lived double? What happens if, instead of
> storing the reference, the result of the access is directly passed along as
> an argument to another function? Would you just give up on eager
> destruction there?
>
This is very similar to the example above with the foo and bar functions.
The short answer is: just don't do that. If you want to keep accessing data
within your matrix, just access it from the matrix itself again, or make a
deep copy. Those are your options. That doesn't seem unreasonable to me.
The idea of merely looking at local uses is starting to grow on me. It
solves the use cases that I presented, and is highly deterministic and easy
for developers to understand. Basically, when the name of the object is
gone, the object is gone. I'm undecided whether local uses of references
and pointers to the object itself should extend its lifetime. On the one
hand it seems straightforward for the compiler to do so, but on the other
hand there's no reason for the developer not to just use the object's name
directly.
Ultimately, the user has the information that is needed and it is trivial
> for them to specify, just as there is no problem with people writing things
> like std::move today.
>
> On Wed, Aug 24, 2016 at 2:17 PM, <nicolas.capens@gmail.com> wrote:
>
>> For example, consider one of the kinds of types that you explicitly
>>> called out: locks. A lock declaration has no actual knowledge of the memory
>>> that it is effectively guarding, so there is no way to *actually* know when
>>> the object is truly done with. Indeed, often times the object isn't even
>>> touched directly *at all* once constructed. Prematurely destroying such an
>>> object would be horrible. This issue is true of basically any object that
>>> has a relationship with another object, such as iterators and their
>>> associated container.
>>>
>>
>> The solution here is to make the lock and the memory that it's guarding
>> part of the same object.
>>
>
> This is not always feasible nor does it actually solve the problem.
>
> On Wed, Aug 24, 2016 at 2:17 PM, <nicolas.capens@gmail.com> wrote:
>
>> This issue is not very different from still having a reference to a local
>> variable after it has gone out of scope. C++ is inherently unsafe, and you
>> simply need to know what you're doing. With lazy destruction, don't use any
>> references to the object after it has gone out of scope. With eager
>> destruction, don't use any references to the object after its last use. A
>> compiler warning could help prevent people from shooting themselves in the
>> foot in both cases.
>>
>
> I'd argue that they are very different and it has everything to do with
> your notion of "last use." This is not something that can actually be
> detected, and if you rely on a naive notion of "use" being someone directly
> touching the object, not even through a reference, then IMO it's
> practically useless and extremely error prone.
>
As far as I can tell it would solve all the examples I had, so it's not
useless. And I think you might only be considering it to be extremely error
prone because you're not used to it. Note that absolute beginners at C++
always have a hard time understanding the relationship between lifetime and
scope. They need to learn the rules of what you can and cannot do. So I
think that if you looked at it as if you're learning the language for the
fist time, eager destruction wouldn't be any more confusing or error prone.
Just stick to a different set of simple rules.
> I'm sorry if I sound overly negative here, but the problems of this are
> already well understood. For any kind of early destruction in a language
> like C++, users would need to be explicit, and that's not bad in this case.
> I genuinely do believe that something similar to this is worthwhile, but
> your particular approach is unrealistic (I think specifically that
> destructive-move would solve a lot of problems with the language and
> library as it is today).
>
I'd like to avoid getting sidetracked too much, but remind me again what
destructive-move would solve that can't be done by overloading the
assignment operator?
--
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/CAE7XuEUZjb7M3wXdv4b%2BSu%3Dt8MmTkAj51dDQDw3qiPMjqZtfRw%40mail.gmail.com.
--001a114c8bbe890069053b0021e7
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On W=
ed, Aug 24, 2016 at 6:00 PM, Matt Calabrese <span dir=3D"ltr"><<a href=
=3D"mailto:calabrese@x.team" target=3D"_blank">calabrese@x.team</a>></sp=
an> wrote:<br><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 class=3D=
"gmail_extra"><div class=3D"gmail_quote"><span class=3D"">On Wed, Aug 24, 2=
016 at 2:17 PM, <span dir=3D"ltr"><<a href=3D"mailto:nicolas.capens@gma=
il.com" target=3D"_blank">nicolas.capens@gmail.com</a>></span> wrote:<br=
></span><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">=
<span class=3D"">On Wednesday, August 24, 2016 at 3:19:24 PM UTC-4, Matt Ca=
labrese wrote:</span><span class=3D""><span><blockquote class=3D"gmail_quot=
e" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204)=
;padding-left:1ex"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div>Wh=
ile I would like C++ to eventually get a way to do the equivalent of this i=
n some form (more generally, I want destructive move, which is related to t=
his even though it may not be immediately obvious),</div></div></div></div>=
</blockquote><div><br></div></span><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'd also like it to be called after the last use as a s=
ource argument too though.</div></span></div></blockquote><div><br></div><d=
iv>Again, the problem is that "last use" isn't something that=
can actually be determined in any meaningful sense. For this to be usable,=
the *user* needs to notate their last use by explicitly calling some kind =
of special destructive operation that doesn't currently exist in the la=
nguage (a hypothetical destructive move operation would be one of those spe=
cial kinds of operations). I and others have given you examples of why what=
you want cannot be done truly automatically in a language like C++.</div><=
/div></div></div></blockquote><div><br></div><div>I'm sorry but that=
9;s simply not true. For all of the <a href=3D"https://groups.google.com/a/=
isocpp.org/forum/#!msg/std-proposals/IUxA4cx8yHc/yKNqKl8hDgAJ">examples</a>=
that I provided, it would suffice to call the destructor after the last <i=
>local</i> use of the variable. The only issue with that is that there'=
s a number of ways in which non-local uses can lead to crashes and whatnot.=
So it's worth exploring if we can improve on the trivial specification=
, but if not, it would still be helpful to have.</div><div><br></div><div>L=
et's not forget that destruction at the end of the scope is not foolpro=
of either:</div><div><br></div><div><font face=3D"monospace, monospace">=C2=
=A0 =C2=A0 int *p;</font></div><div><font face=3D"monospace, monospace">=C2=
=A0 =C2=A0 {</font></div><div><font face=3D"monospace, monospace">=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 int i;</font></div><div><font face=3D"monospace, monos=
pace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 p =3D &i;</font></div><div><font face=
=3D"monospace, monospace">=C2=A0 =C2=A0 }</font></div><div><font face=3D"mo=
nospace, monospace">=C2=A0 =C2=A0 *p =3D 0; =C2=A0 // Yikes!</font></div><d=
iv><br></div><div>And this can happen in very subtle ways:</div><div><br></=
div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 {</font></div><d=
iv><font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 int i;</=
font></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 foo(i);</font></div><div><font face=3D"monospace, monospace">=C2=A0 =
=C2=A0 }</font></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0=
bar();</font></div><div><br></div><div><font face=3D"monospace, monospace"=
>foo()</font> could be taking <font face=3D"monospace, monospace">i</font>&=
#39;s address and bar could try to dereference it.</div><div><br></div><div=
>All I'm saying is let's not pretend that destruction at end of sco=
pe solves the last use issue in the absolute sense. It's a compromise, =
that happens to be well understood. So we don't have to shoot for the s=
tars for eager destruction either. Destruction at the last local use seems =
like a workable starting point to me.</div><div>=C2=A0</div><blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;pa=
dding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"g=
mail_quote"><span class=3D""><div>On Wed, Aug 24, 2016 at 2:17 PM,=C2=A0<sp=
an dir=3D"ltr"><<a href=3D"mailto:nicolas.capens@gmail.com" target=3D"_b=
lank">nicolas.capens@gmail.com</a>></span><wbr>=C2=A0wrote:=C2=A0</div><=
blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-l=
eft:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><span><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-lef=
t:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div><div c=
lass=3D"gmail_quote"><div>I do not think that the appropriate place to nota=
te the premature destruction is on the destructor declaration. Instead, I b=
elieve 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></b=
lockquote><div><br></div></span><div>I wouldn't call it premature destr=
uction. Eager instead of today's lazy destruction at the end of the sco=
pe, seems like a better description to me.</div></div></blockquote><div><br=
></div></span><div>There is no way in practice to implicitly know when an o=
bject is okay to be disposed of without the user providing such information=
..</div><span class=3D""><div><br></div><div>On Wed, Aug 24, 2016 at 2:17 PM=
,=C2=A0<span dir=3D"ltr"><<a href=3D"mailto:nicolas.capens@gmail.com" ta=
rget=3D"_blank">nicolas.capens@gmail.com</a>></span><wbr>=C2=A0wrote:=C2=
=A0<br></div><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>Anyway, for the use cases that I envision, the annotation at dest=
ructor declaration is appropriate. For example say I need a huge matrix to =
temporarily store some intermediate results. I could use "double matri=
x[10000][10000];" and rely on the compiler's optimizations to use =
the memory for other purposes as soon as I'm done with this matrix. But=
it's simply not going to fit on the stack. So instead I'll use an =
object with a pointer to heap memory. But now it only gets freed when it go=
es out of scope. So I want to make it clear to the compiler that I'd li=
ke it to be destroyed eagerly, and not just for this one but for every inst=
ance. It's a property of the class itself that I want it's destruct=
or to be called eagerly. If I don't want that behavior I can simply use=
an equivalent class without eager destructor.<br></div></div></blockquote>=
<div><br></div></span><div>Before again going into the subtleties of why an=
notation strictly at the type level won't work, just think about what y=
ou've said -- the user would have to use an equivalent type without eag=
er destruction if they didn't want this behavior. So now you have two t=
ypes that do exactly the same thing but one with an "eager" destr=
uctor?</div></div></div></div></blockquote><div><br></div><div>No, not real=
ly. All practical use cases of a Matrix class could use eager destruction. =
A well written support library for it would avoid storing references that c=
ould lead to another use after it was destructed eagerly after the last use=
in the scope where the object was defined.</div><div><br></div><div>Also k=
eep in mind that you can still take explicit control over its lifetime usin=
g new/delete. I'm only proposing an alternative implicit lifetime for l=
ocal variables.</div><div><br></div><div>I only mentioned the possibility o=
f having two kinds of classes with different destructor behavior for cases =
like a mutex lock. Some locks make good use of the destruction at end of sc=
ope behavior, while <a href=3D"https://groups.google.com/a/isocpp.org/forum=
/#!msg/std-proposals/IUxA4cx8yHc/yKNqKl8hDgAJ">others</a> would benefit fro=
m releasing sooner. For well designed classes it should be intuitive. And t=
here shouldn't be two otherwise identical classes with different destru=
ctor behavior that you'd use at the same time. Perhaps I shouldn't =
have used the word "equivalent" before. I merely meant that in th=
e sense of for example a different matrix library which does store referenc=
es for later use, and so the designer of the library can decide not to use =
eager destruction.</div><div><br></div><div>It doesn't seem useful to m=
e to specify it on a per-object basis. It would be much harder to use than =
a framework which was designed from the ground up to only use eager destruc=
tion on certain types. Not to mention the syntax for this would probably be=
cumbersome and distracting. Anyway, feel free to give me a counter-example=
where it's not reasonable to choose between lazy or eager destruction =
at the type declaration and have a library built for it with that choice in=
mind.</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr=
"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div>As I'll re=
iterate, the user effectively needs to somehow notate at the usage point wh=
ere they are done with the object, but even if you don't get that argum=
ent, certainly your desire for two equivalent types should hint to you that=
someone would at least want to put the notation at the point of declaratio=
n of the *object* that they want "eagerly" disposed of, instead o=
f having it be a part of the type. This removes the need for multiple types=
that you describe.</div><div><br></div><div>Anyway, apart from that, anoth=
er simple example of where this breaks down: you have your matrix type that=
you've described and some accessor taking a row index and a column ind=
ex. This function returns a reference to an element of that matrix. Someone=
uses the function to access an element. When is your matrix ready for disp=
osal? Nobody is 'touching" your matrix type immediately after you =
call that function, but a reference to one of its elements still exists. St=
rictly speaking, the matrix could be "eagerly" destroyed as soon =
as the accessor function returns, before the element is even truly accessed=
through the reference. Even if you delay your disposal until the end of th=
e full expression, what happens if the reference is stored and accessed in =
the next statement? This is not at all an unreasonable scenario. Do you exp=
ect to track such references? If so, why -- how would the compiler know whi=
ch references to track. Is the compiler expected to know that the reference=
which is returned corresponds to something that is owned by the object tha=
t was accessed as opposed to just a reference to some other, longer-lived d=
ouble? What happens if, instead of storing the reference, the result of the=
access is directly passed along as an argument to another function? Would =
you just give up on eager destruction there?</div></div></div></div></block=
quote><div><br></div><div>This is very similar to the example above with th=
e foo and bar functions. The short answer is: just don't do that. If yo=
u want to keep accessing data within your matrix, just access it from the m=
atrix itself again, or make a deep copy. Those are your options. That doesn=
't seem unreasonable to me.</div><div><br></div><div>The idea of merely=
looking at local uses is starting to grow on me. It solves the use cases t=
hat I presented, and is highly deterministic and easy for developers to und=
erstand. Basically, when the name of the object is gone, the object is gone=
.. I'm undecided whether local uses of references and pointers to the ob=
ject itself should extend its lifetime. On the one hand it seems straightfo=
rward for the compiler to do so, but on the other hand there's no reaso=
n for the developer not to just use the object's name directly.</div><d=
iv><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;b=
order-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"=
gmail_extra"><div class=3D"gmail_quote"><div>Ultimately, the user has the i=
nformation that is needed and it is trivial for them to specify, just as th=
ere is no problem with people writing things like std::move today.</div><sp=
an class=3D""><div><br></div><div>On Wed, Aug 24, 2016 at 2:17 PM,=C2=A0<sp=
an dir=3D"ltr"><<a href=3D"mailto:nicolas.capens@gmail.com" target=3D"_b=
lank">nicolas.capens@gmail.com</a>></span><wbr>=C2=A0wrote:=C2=A0</div><=
blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-l=
eft:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><span><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-lef=
t:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div><div c=
lass=3D"gmail_quote"><div>For example, consider one of the kinds of types t=
hat you explicitly called out: locks. A lock declaration has no actual know=
ledge of the memory that it is effectively guarding, so there is no way to =
*actually* know when the object is truly done with. Indeed, often times the=
object isn't even touched directly *at all* once constructed. Prematur=
ely destroying such an object would be horrible. This issue is true of basi=
cally any object that has a relationship with another object, such as itera=
tors and their associated container.</div></div></div></div></blockquote><d=
iv><br></div></span><div>The solution here is to make the lock and the memo=
ry that it's guarding part of the same object.</div><span><div></div></=
span></div></blockquote><div><br></div></span><div>This is not always feasi=
ble nor does it actually solve the problem.</div><span class=3D""><div><br>=
</div><div>On Wed, Aug 24, 2016 at 2:17 PM,=C2=A0<span dir=3D"ltr"><<a h=
ref=3D"mailto:nicolas.capens@gmail.com" target=3D"_blank">nicolas.capens@gm=
ail.com</a>></span><wbr>=C2=A0wrote:=C2=A0</div><blockquote class=3D"gma=
il_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,2=
04,204);padding-left:1ex"><div dir=3D"ltr"><div>This issue is not very diff=
erent from still having a reference to a local variable after it has gone o=
ut of scope. C++ is inherently unsafe, and you simply need to know what you=
're doing. With lazy destruction, don't use any references to the o=
bject after it has gone out of scope. With eager destruction, don't use=
any references to the object after its last use. A compiler warning could =
help prevent people from shooting themselves in the foot in both cases.</di=
v></div></blockquote><div><br></div></span><div>I'd argue that they are=
very different and it has everything to do with your notion of "last =
use." This is not something that can actually be detected, and if you =
rely on a naive notion of "use" being someone directly touching t=
he object, not even through a reference, then IMO it's practically usel=
ess and extremely error prone.</div></div></div></div></blockquote><div><br=
></div><div>As far as I can tell it would solve all the examples I had, so =
it's not useless. And I think you might only be considering it to be ex=
tremely error prone because you're not used to it. Note that absolute b=
eginners at C++ always have a hard time understanding the relationship betw=
een lifetime and scope. They need to learn the rules of what you can and ca=
nnot do. So I think that if you looked at it as if you're learning the =
language for the fist time, eager destruction wouldn't be any more conf=
using or error prone. Just stick to a different set of simple rules.</div><=
div>=C2=A0</div><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 class=
=3D"gmail_extra"><div class=3D"gmail_quote"><div>I'm sorry if I sound o=
verly negative here, but the problems of this are already well understood. =
For any kind of early destruction in a language like C++, users would need =
to be explicit, and that's not bad in this case. I genuinely do believe=
that something similar to this is worthwhile, but your particular approach=
is unrealistic (I think specifically that destructive-move would solve a l=
ot of problems with the language and library as it is today).</div></div></=
div></div>
</blockquote></div></div><div class=3D"gmail_extra"><br></div><div class=3D=
"gmail_extra">I'd like to avoid getting sidetracked too much, but remin=
d me again what destructive-move would solve that can't be done by over=
loading the assignment operator?</div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/CAE7XuEUZjb7M3wXdv4b%2BSu%3Dt8MmTkAj5=
1dDQDw3qiPMjqZtfRw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAE7XuEUZjb7M=
3wXdv4b%2BSu%3Dt8MmTkAj51dDQDw3qiPMjqZtfRw%40mail.gmail.com</a>.<br />
--001a114c8bbe890069053b0021e7--
.
Author: Nicolas Capens <nicolas.capens@gmail.com>
Date: Fri, 26 Aug 2016 17:38:45 -0400
Raw View
--94eb2c058454d91b0e053b0056ab
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Wed, Aug 24, 2016 at 6:41 PM, Thiago Macieira <thiago@macieira.org>
wrote:
> Em quarta-feira, 24 de agosto de 2016, =C3=A0s 13:16:30 PDT,
> nicolas.capens@gmail.com escreveu:
> > > Define "last use".
> >
> > The last use according to liveness analysis.
>
> Let's make it stricter: the last time the object is formally ODR-used.
>
ODR as in One Definition Rule? That is, the last time you're using the
object's name?
Yes, I'm starting to think that might actually be sufficient, or at least a
good starting point.
> But then, what happens to lifetime extension via references?
>
> resource a;
> const resource &r =3D a;
>
> When does a get destroyed?
I'm on the fence about that. One the one hand it seems easy to extend the
lifetime to the last use of either a or r. On the other hand, it's really
just a useless alias and you could use a instead. Last use of the object's
name seems like a very simple deterministic rule that's also easy to
comprehend by developers. You wouldn't have to check for references if you
wanted to verify your object's lifetimes visually.
The other option is to be conservative. Let the compiler track references,
and even check whether functions for which it knows the definition store
any of these references for later use. If it can't determine that, give up
and destruct at the end of the scope. It would allow for some other usage
patterns, but I'm starting to think those might not be of much value and
not worth the analysis cost and loss of determinism. I haven't ruled it out
yet though... Opinions welcome.
> --
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
> Software Architect - Intel Open Source Technology Center
>
>
--=20
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 e=
mail 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/CAE7XuEXByDUJ-SHNvU47cycPROcVYGtkFPnS0HHiu4czPBM=
R4w%40mail.gmail.com.
--94eb2c058454d91b0e053b0056ab
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On W=
ed, Aug 24, 2016 at 6:41 PM, Thiago Macieira <span dir=3D"ltr"><<a href=
=3D"mailto:thiago@macieira.org" target=3D"_blank">thiago@macieira.org</a>&g=
t;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0=
.8ex;border-left:1px #ccc solid;padding-left:1ex">Em quarta-feira, 24 de a=
gosto de 2016, =C3=A0s 13:16:30 PDT,<br>
<a href=3D"mailto:nicolas.capens@gmail.com">nicolas.capens@gmail.com</a> es=
creveu:<br>
<span class=3D"">> > Define "last use".<br>
><br>
> The last use according to liveness analysis.<br>
<br>
</span>Let's make it stricter: the last time the object is formally ODR=
-used.<br></blockquote><div><br></div><div>ODR as in One Definition Rule? T=
hat is, the last time you're using the object's name?</div><div><br=
></div><div>Yes, I'm starting to think that might actually be sufficien=
t, or at least a good starting point.</div><div>=C2=A0</div><blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;pa=
dding-left:1ex">
But then, what happens to lifetime extension via references?<br>
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 resource a;<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 const resource &r =3D a;<br>
<br>
When does a get destroyed?</blockquote><div><br></div><div>I'm on the f=
ence about that. One the one hand it seems easy to extend the lifetime to t=
he last use of either <font face=3D"monospace, monospace">a</font> or <font=
face=3D"monospace, monospace">r</font>. On the other hand, it's really=
just a useless alias and you could use <font face=3D"monospace, monospace"=
>a</font> instead. Last use of the object's name seems like a very simp=
le deterministic rule that's also easy to comprehend by developers. You=
wouldn't have to check for references if you wanted to verify your obj=
ect's lifetimes visually.</div><div><br></div><div>The other option is =
to be conservative. Let the compiler track references, and even check wheth=
er functions for which it knows the definition store any of these reference=
s for later use. If it can't determine that, give up and destruct at th=
e end of the scope. It would allow for some other usage patterns, but I'=
;m starting to think those might not be of much value and not worth the ana=
lysis cost and loss of determinism. I haven't ruled it out yet though..=
.. Opinions welcome.</div><div>=C2=A0</div><blockquote class=3D"gmail_quote"=
style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv class=3D"HOEnZb"><div class=3D"h5">
--<br>
Thiago Macieira - thiago (AT) <a href=3D"http://macieira.info" rel=3D"noref=
errer" target=3D"_blank">macieira.info</a> - thiago (AT) <a href=3D"http://=
kde.org" rel=3D"noreferrer" target=3D"_blank">kde.org</a><br>
=C2=A0 =C2=A0Software Architect - Intel Open Source Technology Center<br>
<br>
</div></div></blockquote></div><br></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/CAE7XuEXByDUJ-SHNvU47cycPROcVYGtkFPnS=
0HHiu4czPBMR4w%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAE7XuEXByDUJ-SHN=
vU47cycPROcVYGtkFPnS0HHiu4czPBMR4w%40mail.gmail.com</a>.<br />
--94eb2c058454d91b0e053b0056ab--
.
Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date: Fri, 26 Aug 2016 19:39:54 -0700 (PDT)
Raw View
------=_Part_192_239867487.1472265594362
Content-Type: multipart/alternative;
boundary="----=_Part_193_793385097.1472265594363"
------=_Part_193_793385097.1472265594363
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Friday, August 26, 2016 at 12:21:42 PM UTC-7, Nicolas Capens wrote:
>
> On Fri, Aug 26, 2016 at 1:16 PM, Ren Industries <renind...@gmail.com=20
> <javascript:>> wrote:
>
>> Why is it such a terrible imposition to require manual interaction to=20
>> enforce this behavior? I don't buy your argument that it is similar to=
=20
>> register allocation; that's a QOI not a standards issue.
>>
>
> Consider this simple statement:
>
> x =3D a * b * c;
>
> Assume they're all scalars, and a, b, and c are no longer used after this=
=20
> statement. That means liveness analysis will make their registers availab=
le=20
> for other variables, without you having to worry about it. But if instead=
=20
> these variables were huge matrices and you had to manually free their=20
> storage to minimize memory consumption, then it would look something like=
=20
> this:
>
> Matrix t =3D a * b;
> a.~Matrix();
> b.~Matrix();
> x =3D t * c;
> t.~Matrix();
> c.~Matrix();
>
Well, it would look like this:
x =3D a * b * c;
a.clear();
b.clear();
c.clear();
Or, if you wanted to be more C++11'ish about it,
x =3D std::move(a) * std::move(b) * std::move(c);
to indicate that you're really done using those named variables. It's=20
really not a big deal.
I hope the above example illustrates that this is very similar to register=
=20
> allocation, and it's a standards issue that we don't get this behavior=20
> today for non-scalar types.
>
You've already realized that we *do* get this behavior today for trivially=
=20
destructible types, and in general we get this behavior for every type *by=
=20
the as-if rule* (for types whose destructors have no observable side=20
effects). Your one remaining concern is that we currently don't get this=
=20
behavior for destructors whose side effects are observable.
Here we *seem to* have two cases:
(Case 1) Destructors whose side effects are "important", such as=20
~std::lock_guard<std::mutex>.
(Case 2) Destructors whose side effects are "unimportant", such as=20
~std::string.
Let's consider what might happen if we allowed std::string's destructor to=
=20
run "eagerly." Some people in this thread have already shown one problem:
std::string x =3D "hello";
char *y =3D &x[0];
use(x);
// run x's destructor now?
std::cout << y << std::endl;
Here, we are done with the variable x, but we aren't done with the object=
=20
referenced by x =E2=80=94 the object that would be destroyed.
But okay, let's postulate that std::string is a bad candidate for eager=20
destruction because it allows the user to get a pointer into its innards.=
=20
After all, std::string also unsafely allows us to do things like this =E2=
=80=94
std::string x =3D "hello";
char *y =3D &x[0];
x =3D "world";
std::cout << y << std::endl; // UB
So let's promise not to do anything stupid with pointers, okay? *Now* are=
=20
we foolproof?
Well. The side-effect of ~std::string that is observable under the current=
=20
rules is its memory deallocation, which results in some calls to operator=
=20
delete[] and so on. What could go wrong if we allow that deallocation to=20
happen eagerly, given that we've promised not to do anything stupid with=20
pointers?
std::string x =3D "hello";
if (true) {
std::lock_guard<std::mutex> lk(mtx);
use(x);
// run x's destructor now?
}
Here we are performing our last operation on x while holding a mutex lock.=
=20
Our last operation ("use(x)") is presumably something cheap and fast, or=20
else we would try to do it outside the lock. But the destructor call, by=20
definition, frees memory, which means it's not cheap. (Allocating memory is=
=20
slower yet, but deallocating memory isn't always super cheap either.) And=
=20
in fact it probably tries to take a global lock itself, under some=20
circumstances, so now we're holding our original lock on "mtx" through a=20
very slow and possibly even *blocking* memory-deallocation operation. Well,=
=20
*that's* not good!
Okay, so we shouldn't use eager destruction for types that expose=20
references to their internals; and we shouldn't use eager destruction for=
=20
types whose destructors might block on synchronization or I/O (because=20
those types might get eagerly destructed under a mutex); and it goes=20
without saying that we shouldn't use eager destruction for types whose=20
destructors might *throw*; and we shouldn't use eager destruction for types=
=20
whose destructors are trivial (because we get eager destruction for free=20
under the as-if rule in those cases).
So what cases have we got left at this point where eager destruction is=20
*possible*? Certainly your motivating use-case of "Matrix" isn't a=20
candidate, both because of the internal-reference problem and because of=20
the memory-deallocation-is-a-blocking-operation problem. My above (Case 1)=
=20
and (Case 2) turn out to have collapsed into a single case:
(Case 1) Destructors whose side effects *might be important to somebody.*
my $.02,
=E2=80=93Arthur
--=20
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 e=
mail 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/2e647ba9-3f9c-4b2a-90c7-bcdffdd4153b%40isocpp.or=
g.
------=_Part_193_793385097.1472265594363
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Friday, August 26, 2016 at 12:21:42 PM UTC-7, 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 Fri, Aug 26, 2016 at 1:16 PM, Ren Industr=
ies <span dir=3D"ltr"><<a href=3D"javascript:" target=3D"_blank" gdf-obf=
uscated-mailto=3D"V6UqK6HtEAAJ" rel=3D"nofollow" onmousedown=3D"this.href=
=3D'javascript:';return true;" onclick=3D"this.href=3D'javascri=
pt:';return true;">renind...@gmail.com</a>></span> wrote:<br><blockq=
uote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1p=
x solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr">Why is it such =
a terrible imposition to require manual interaction to enforce this behavio=
r? I don't buy your argument that it is similar to register allocation;=
that's a QOI not a standards issue.</div></blockquote><div><br></div><=
div>Consider this simple statement:</div><div><br></div><div>=C2=A0 =C2=A0 =
x =3D a * b * c;</div><div><br></div><div>Assume they're all scalars, a=
nd a, b, and c are no longer used after this statement. That means liveness=
analysis will make their registers available for other variables, without =
you having to worry about it. But if instead these variables were huge matr=
ices and you had to manually free their storage to minimize memory consumpt=
ion, then it would look something like this:</div><div><br></div><div>=C2=
=A0 =C2=A0 Matrix t =3D a * b;</div><div>=C2=A0 =C2=A0 a.~Matrix();</div><d=
iv>=C2=A0 =C2=A0 b.~Matrix();</div><div>=C2=A0 =C2=A0 x =3D t * c;</div><di=
v>=C2=A0 =C2=A0 t.~Matrix();</div><div>=C2=A0 =C2=A0 c.~Matrix();</div></di=
v></div></div></blockquote><div><br></div><div>Well, it would look like thi=
s:</div><div><br></div><div>=C2=A0 =C2=A0 x =3D a * b * c;</div><div>=C2=A0=
=C2=A0 a.clear();</div><div>=C2=A0 =C2=A0 b.clear();</div><div>=C2=A0 =C2=
=A0 c.clear();</div><div><br></div><div>Or, if you wanted to be more C++11&=
#39;ish about it,</div><div><br></div><div>=C2=A0 =C2=A0 x =3D std::move(a)=
* std::move(b) * std::move(c);</div><div><br></div><div>to indicate that y=
ou're really done using those named variables. It's really not a bi=
g deal.</div><div><br></div><blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><d=
iv dir=3D"ltr"><div class=3D"gmail_quote"><div>I hope the above example ill=
ustrates that this is very similar to register allocation, and it's a s=
tandards issue that we don't get this behavior today for non-scalar typ=
es.<br></div></div></div></blockquote><div><br></div><div>You've alread=
y realized that we <i>do</i> get this behavior today for trivially destruct=
ible types, and in general we get this behavior for every type <i>by the as=
-if rule</i> (for types whose destructors have no observable side effects).=
=C2=A0Your one remaining concern is that we currently don't get this b=
ehavior for destructors whose side effects are observable.</div><div><br></=
div><div>Here we <i><b>seem to</b></i> have two cases:</div><div>(Case 1) D=
estructors whose side effects are "important", such as ~std::lock=
_guard<std::mutex>.</div><div>(Case 2) Destructors whose side effects=
are "unimportant", such as ~std::string.</div><div><br></div><di=
v>Let's consider what might happen if we allowed std::string's dest=
ructor to run "eagerly." =C2=A0Some people in this thread have al=
ready shown one problem:</div><div><br></div><div>=C2=A0 =C2=A0 std::string=
x =3D "hello";</div><div>=C2=A0 =C2=A0 char *y =3D &x[0];</d=
iv><div>=C2=A0 =C2=A0 use(x);</div><div>=C2=A0 =C2=A0 // run x's destru=
ctor now?</div><div><div>=C2=A0 =C2=A0 std::cout << y << std::e=
ndl;</div></div><div><br></div><div>Here, we are done with the variable x, =
but we aren't done with the object referenced by x =E2=80=94 the object=
that would be destroyed.</div><div>But okay, let's postulate that std:=
:string is a bad candidate for eager destruction because it allows the user=
to get a pointer into its innards. After all, std::string also unsafely al=
lows us to do things like this =E2=80=94</div><div><br></div><div><div>=C2=
=A0 =C2=A0 std::string x =3D "hello";</div><div>=C2=A0 =C2=A0 cha=
r *y =3D &x[0];</div></div><div>=C2=A0 =C2=A0 x =3D "world";<=
/div><div>=C2=A0 =C2=A0 std::cout << y << std::endl; =C2=A0// U=
B</div><div><br></div><div>So let's promise not to do anything stupid w=
ith pointers, okay? <i>Now</i> are we foolproof?</div><div>Well. The side-e=
ffect of ~std::string that is observable under the current rules is its mem=
ory deallocation, which results in some calls to operator delete[] and so o=
n. What could go wrong if we allow that deallocation to happen eagerly, giv=
en that we've promised not to do anything stupid with pointers?</div><d=
iv><br></div><div>=C2=A0 =C2=A0 std::string x =3D "hello";</div><=
div>=C2=A0 =C2=A0 if (true) {</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 std::lo=
ck_guard<std::mutex> lk(mtx);</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 u=
se(x);</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 // run x's destructor now?=
</div><div></div><div>=C2=A0 =C2=A0 }<br></div><div><br></div><div>Here we =
are performing our last operation on x while holding a mutex lock. Our last=
operation ("use(x)") is presumably something cheap and fast, or =
else we would try to do it outside the lock. But the destructor call, by de=
finition, frees memory, which means it's not cheap. (Allocating memory =
is slower yet, but deallocating memory isn't always super cheap either.=
) And in fact it probably tries to take a global lock itself, under some ci=
rcumstances, so now we're holding our original lock on "mtx" =
through a very slow and possibly even <i>blocking</i> memory-deallocation o=
peration. Well, <i>that's</i> not good!</div><div><br></div><div>Okay, =
so we shouldn't use eager destruction for types that expose references =
to their internals; and we shouldn't use eager destruction for types wh=
ose destructors might block on synchronization or I/O (because those types =
might get eagerly destructed under a mutex); and it goes without saying tha=
t we shouldn't use eager destruction for types whose destructors might =
<i>throw</i>; and we shouldn't use eager destruction for types whose de=
structors are trivial (because we get eager destruction for free under the =
as-if rule in those cases).</div><div><br></div><div>So what cases have we =
got left at this point where eager destruction is <i>possible</i>? Certainl=
y your motivating use-case of "Matrix" isn't a candidate, bot=
h because of the internal-reference problem and because of the memory-deall=
ocation-is-a-blocking-operation problem. =C2=A0My above (Case 1) and (Case =
2) turn out to have collapsed into a single case:</div><div>(Case 1) Destru=
ctors whose side effects <i>might be important to somebody.</i></div><div><=
br></div><div>my $.02,</div><div>=E2=80=93Arthur</div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/2e647ba9-3f9c-4b2a-90c7-bcdffdd4153b%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/2e647ba9-3f9c-4b2a-90c7-bcdffdd4153b=
%40isocpp.org</a>.<br />
------=_Part_193_793385097.1472265594363--
------=_Part_192_239867487.1472265594362--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 27 Aug 2016 08:10:55 -0700 (PDT)
Raw View
------=_Part_245_1912908355.1472310656044
Content-Type: multipart/alternative;
boundary="----=_Part_246_1807987271.1472310656045"
------=_Part_246_1807987271.1472310656045
Content-Type: text/plain; charset=UTF-8
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.
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.
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*.
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;
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`?
--
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/16f4f27a-daf4-4eff-8408-73aadc99e0c5%40isocpp.org.
------=_Part_246_1807987271.1472310656045
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Thursday, August 25, 2016 at 5:24:39 PM UTC-4, Nicolas =
Capens wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">=
Thanks all for the initial feedback! It's clear to me now that I haven&=
#39;t defined "last use" very well, and giving it an accurate def=
inition based on my limited knowledge of compiler lingo is going to be tric=
ky.<div><br></div><div>So let me take a step back and describe what real-wo=
rld 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 wh=
ere a scalar variable's register would be made available for a differen=
t variable:</div></div></blockquote><div><br>I don't think anyone misun=
derstands what your <i>intended use cases</i> are. But the fact is that thi=
ngs do not get used the way they are intended at all times.<br><br>Consider=
a basic bit of template programming:<br><br><div class=3D"prettyprint" sty=
le=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187=
); border-style: solid; border-width: 1px; word-wrap: break-word;"><code cl=
ass=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">T t </span><span style=3D"color: #660;" cl=
ass=3D"styled-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-pretti=
fy"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">au=
to</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> tpl </s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> forward_as_tuple</s=
pan><span 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>This code, today, works for any type `T` which can be constructed with w=
hatever ... was. Your feature would now make this code <i>suspect</i>. It w=
ould <i>only work</i> for `T`s that do not use "eager" destructio=
n. So if someone wanted to instantiate this template with your `Matrix` typ=
e, this code breaks.<br><br>Normal amounts of compiler analysis cannot fix =
that. After all, the compiler doesn't (necessarily) know what's goi=
ng on in `forward_as_tuple`. All the compiler sees is that you're passi=
ng a reference in, and you're getting at tuple<T&> out. How c=
ould the compiler know that `tpl` contains a reference to `t`? It can't=
; not without doing <i>serious</i> usage analysis.<br><br>And that's fo=
r a <i>simple</i> case; `forward_as_tuple` is a template function, so the c=
ompiler 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 <i>for certain</i> that the return value contains a reference to a=
function parameter.<br><br>Remember: this is the confounding problem with =
temporary lifetime extension, when passing temporaries through functions.<b=
r><br>Who's fault is this failure? Is it the fault of the person who wr=
ote 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 pas=
sed `Matrix` to this template. But how could they know that `Matrix`'s =
eager destructor would cause the template to break?<br><br>Thus, the blame =
must fall on the feature itself.<br><br>Your post talks about the utility o=
f this feature with "scalar types". But what you're really ta=
lking 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 it=
s contents. But note where this distinction is made. It's not made in t=
he type's declaration (you can get references to `int`, after all). It&=
#39;s made <i>at the point of use</i>.<br><br>The problem, as Matt has said=
, is that your feature works at the <i>type</i> level. To make this feature=
work, it has to happen at the <i>usage</i> level. The person declaring tha=
t variable <i>must explicitly state</i> that they will use the type as a pu=
re value. That they won't get pointers/references to itself or its cont=
ents.<br><br>The right way to handle this is to make it a function of the o=
bject's declaration:<br><br><div class=3D"prettyprint" style=3D"backgro=
und-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-sty=
le: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"pretty=
print"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"=
styled-by-prettify"><some_syntax></span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> TypeName varName;</span></div></code></div><b=
r>That would cause the compiler to destroy the variable after its last name=
d use.<br><br>This allows template programming to actually work. If a templ=
ate function needed to use eager destruction, then the template would expre=
ss that in the declaration of an automatic variable. And therefore, the per=
son writing that template function would know that they cannot do tricks on=
the variable like `forward_as_tuple`.<br><br>Also, there still need to be =
clarifications on what "last use" means. Consider:<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: #606;" class=3D"styled-by-prettify">Matrix</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> a </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"col=
or: #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"st=
yled-by-prettify">for</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
">loop</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><span styl=
e=3D"color: #606;" class=3D"styled-by-prettify">Matrix</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> b </span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> a </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">*</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> whatever</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br>=C2=A0 </span><span style=3D"color: #800;" class=3D"styled-by-pret=
tify">//Do stuff with b, without using a</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br></span></div></code></div><br>When does `a` get destroye=
d? I guess it would have to be after the loop, right? Otherwise, the compil=
er would have to advance the loop prematurely to see if `a` needs to be des=
troyed.<br><br>How does this work with conditional branching? Or God help y=
ou, with `goto`?</div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/16f4f27a-daf4-4eff-8408-73aadc99e0c5%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/16f4f27a-daf4-4eff-8408-73aadc99e0c5=
%40isocpp.org</a>.<br />
------=_Part_246_1807987271.1472310656045--
------=_Part_245_1912908355.1472310656044--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 27 Aug 2016 13:54:46 -0700 (PDT)
Raw View
------=_Part_2939_411434266.1472331287005
Content-Type: multipart/alternative;
boundary="----=_Part_2940_1011417906.1472331287006"
------=_Part_2940_1011417906.1472331287006
Content-Type: text/plain; charset=UTF-8
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).
--
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/e94c3ab8-e064-4dcb-a702-3999a877d264%40isocpp.org.
------=_Part_2940_1011417906.1472331287006
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<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>anything</i>.=
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.<br><br>If eage=
r destruction is as important as you believe it is, then I shouldn't ha=
ve to write a wrapper type around `vector` or `deque` or whatever just to g=
et 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 ru=
les).<br></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/e94c3ab8-e064-4dcb-a702-3999a877d264%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/e94c3ab8-e064-4dcb-a702-3999a877d264=
%40isocpp.org</a>.<br />
------=_Part_2940_1011417906.1472331287006--
------=_Part_2939_411434266.1472331287005--
.
Author: "D. B." <db0451@gmail.com>
Date: Sat, 27 Aug 2016 22:03:34 +0100
Raw View
--001a11443ae4dab533053b13f620
Content-Type: text/plain; charset=UTF-8
Nicol: Absolutely. Eager destruction should be a strictly opt-in feature.
And it would be better if *anyone* could opt into it, with any objects they
nominate, rather than only those whose interfaces they can edit.
So +1 for the idea of this being an attribute not of a destructor itself,
but rather of the declaration - as a *hint* to the optimiser that it can
proceed as-if no one (or no one in immediate scope) has stashed a handle to
the instance and use that to deallocate early, *iff* it sees value.
That said, I wonder how likely this is, given that by my understanding,
we're far into GC territory. But as a non-binding hint to the compiler that
wouldn't affect semantics of well-formed programs, maybe it's not that
outlandish at all... we have several of those already.
--
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/CACGiwhEWxXQbm60FDcAxH%2BKA3rMnFcpvRnpbUBaQ-HtGuZwzAQ%40mail.gmail.com.
--001a11443ae4dab533053b13f620
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>Nicol: Absolutely. Eager destruction should be a stri=
ctly opt-in feature. And it would be better if <i>anyone</i> could opt into=
it, with any objects they nominate, rather than only those whose interface=
s they can edit.<br><br> So +1 for the idea of this being an attribute not =
of a destructor itself, but rather of the declaration - as a <i>hint</i> to=
the optimiser that it can proceed as-if no=20
one (or no one in immediate scope) has stashed a handle to the instance and=
use that to deallocate early, <i>iff</i> it sees value.<br><br></div>That =
said, I wonder how likely this is, given that by my understanding, we'r=
e far into GC territory. But as a non-binding hint to the compiler that wou=
ldn't affect semantics of well-formed programs, maybe it's not that=
outlandish at all... we have several of those already.<br></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/CACGiwhEWxXQbm60FDcAxH%2BKA3rMnFcpvRn=
pbUBaQ-HtGuZwzAQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CACGiwhEWxXQbm6=
0FDcAxH%2BKA3rMnFcpvRnpbUBaQ-HtGuZwzAQ%40mail.gmail.com</a>.<br />
--001a11443ae4dab533053b13f620--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 27 Aug 2016 15:48:08 -0700 (PDT)
Raw View
------=_Part_2981_800077247.1472338088653
Content-Type: multipart/alternative;
boundary="----=_Part_2982_434029292.1472338088654"
------=_Part_2982_434029292.1472338088654
Content-Type: text/plain; charset=UTF-8
On Saturday, August 27, 2016 at 5:03:38 PM UTC-4, D. B. wrote:
>
> Nicol: Absolutely. Eager destruction should be a strictly opt-in feature.
> And it would be better if *anyone* could opt into it, with any objects
> they nominate, rather than only those whose interfaces they can edit.
>
> So +1 for the idea of this being an attribute not of a destructor itself,
> but rather of the declaration - as a *hint* to the optimiser that it can
> proceed as-if no one (or no one in immediate scope) has stashed a handle to
> the instance and use that to deallocate early, *iff* it sees value.
>
Hmm. At first, I didn't like the idea of it being merely a hint to the
optimizer. When a destructor gets called is an observable side-effect for
any code where we would care to use such a thing. So it should be something
you could rely on.
After thinking about it for a bit however, making it a hint does solve a
number of issues. The most important being the exact definition of "last
use". We don't have to have one anymore.
So if you use this attribute on an automatic variable (and having it be a
genuine C++ attribute is a legitimate use case), then it says three things.
1. The compiler may call the object's destructor out of the normal order.
2. The object's destructor will only be called after the last time a
particular path of execution uses that variable's name.
3. You promise that pointers/references to the object or any object that
depends on the destructor *not* having been executed will not be used after
point #2.
We then wouldn't need to define anything beyond that. Compilers would be
free to do simple analysis for basic cases, but if there is complex
conditional logic that makes it hard to determine where "last use" happens,
they are also free to just fall back to the standard behavior.
In this way, it becomes something like named return value elision. A lot of
compilers will provide it, so long as your code doesn't get too complex. We
know it'll almost certainly work in the simple case of `Type name = ...;
/*do stuff*/ return name;`. But if there are multiple return statements and
so forth, we become less certain of a compiler's ability to do it.
The same would be true here. The more complex the logic, the less reliable
the feature becomes.
That said, I wonder how likely this is, given that by my understanding,
> we're far into GC territory. But as a non-binding hint to the compiler that
> wouldn't affect semantics of well-formed programs, maybe it's not that
> outlandish at all... we have several of those already.
>
But it would affect the semantics of well-formed programs. See my tuple
example above; if `T t` had been annotated with the attribute, then it
would make use of `tpl` without the use of `t` undefined behavior. That's
part of the promise you make when you use [[eager-destruct]] or whatever we
call it.
It's no different from [[noreturn]] in that regard; if such a function ever
actually *returns*, you provoke UB.
--
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/52303ad8-6485-49e6-b797-da61d270627e%40isocpp.org.
------=_Part_2982_434029292.1472338088654
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Saturday, August 27, 2016 at 5:03:38 PM UTC-4, D. B. wr=
ote:<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>Nico=
l: Absolutely. Eager destruction should be a strictly opt-in feature. And i=
t would be better if <i>anyone</i> could opt into it, with any objects they=
nominate, rather than only those whose interfaces they can edit.<br><br> S=
o +1 for the idea of this being an attribute not of a destructor itself, bu=
t rather of the declaration - as a <i>hint</i> to the optimiser that it can=
proceed as-if no=20
one (or no one in immediate scope) has stashed a handle to the instance and=
use that to deallocate early, <i>iff</i> it sees value.<br></div></div></b=
lockquote><div><br>Hmm. At first, I didn't like the idea of it being me=
rely a hint to the optimizer. When a destructor gets called is an observabl=
e side-effect for any code where we would care to use such a thing. So it s=
hould be something you could rely on.<br><br>After thinking about it for a =
bit however, making it a hint does solve a number of issues. The most impor=
tant being the exact definition of "last use". We don't have =
to have one anymore.<br><br>So if you use this attribute on an automatic va=
riable (and having it be a genuine C++ attribute is a legitimate use case),=
then it says three things.<br><br>1. The compiler may call the object'=
s destructor out of the normal order.<br><br>2. The object's destructor=
will only be called after the last time a particular path of execution use=
s that variable's name.<br><br>3. You promise that pointers/references =
to the object or any object that depends on the destructor <i>not</i> havin=
g been executed will not be used after point #2.<br><br>We then wouldn'=
t need to define anything beyond that. Compilers would be free to do simple=
analysis for basic cases, but if there is complex conditional logic that m=
akes it hard to determine where "last use" happens, they are also=
free to just fall back to the standard behavior.<br><br>In this way, it be=
comes something like named return value elision. A lot of compilers will pr=
ovide it, so long as your code doesn't get too complex. We know it'=
ll almost certainly work in the simple case of `Type name =3D ...; /*do stu=
ff*/ return name;`. But if there are multiple return statements and so fort=
h, we become less certain of a compiler's ability to do it.<br><br>The =
same would be true here. The more complex the logic, the less reliable the =
feature becomes.<br><br></div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">=
<div dir=3D"ltr"><div></div>That said, I wonder how likely this is, given t=
hat by my understanding, we're far into GC territory. But as a non-bind=
ing hint to the compiler that wouldn't affect semantics of well-formed =
programs, maybe it's not that outlandish at all... we have several of t=
hose already.<br></div></blockquote><div><br>But it would affect the semant=
ics of well-formed programs. See my tuple example above; if `T t` had been =
annotated with the attribute, then it would make use of `tpl` without the u=
se of `t` undefined behavior. That's part of the promise you make when =
you use [[eager-destruct]] or whatever we call it.<br><br>It's no diffe=
rent from [[noreturn]] in that regard; if such a function ever actually <i>=
returns</i>, you provoke UB.<br></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/52303ad8-6485-49e6-b797-da61d270627e%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/52303ad8-6485-49e6-b797-da61d270627e=
%40isocpp.org</a>.<br />
------=_Part_2982_434029292.1472338088654--
------=_Part_2981_800077247.1472338088653--
.
Author: "D. B." <db0451@gmail.com>
Date: Sun, 28 Aug 2016 09:06:11 +0100
Raw View
--001a1147284e8f7fac053b1d3863
Content-Type: text/plain; charset=UTF-8
On Sat, Aug 27, 2016 at 11:48 PM, Nicol Bolas <jmckesson@gmail.com> wrote:
>
> Hmm. At first, I didn't like the idea of it being merely a hint to the
> optimizer. When a destructor gets called is an observable side-effect for
> any code where we would care to use such a thing. So it should be something
> you could rely on.
>
> After thinking about it for a bit however, making it a hint does solve a
> number of issues.
>
Heh, I thought I was just inferring what you meant, but instead I came up
with a new idea. That was unexpectedly useful! The rest of what you said is
a good (probably better than I could've written) outline of what I was
thinking. So thanks! Although:
> That said, I wonder how likely this is, given that by my understanding,
>> we're far into GC territory. But as a non-binding hint to the compiler that
>> wouldn't affect semantics of well-formed programs, maybe it's not that
>> outlandish at all... we have several of those already.
>>
>
> But it would affect the semantics of well-formed programs. See my tuple
> example above; if `T t` had been annotated with the attribute, then it
> would make use of `tpl` without the use of `t` undefined behavior. That's
> part of the promise you make when you use [[eager-destruct]] or whatever we
> call it.
>
> It's no different from [[noreturn]] in that regard; if such a function
> ever actually *returns*, you provoke UB.
>
> Not sure if this was an imprecise choice of words on my part. But what I
really meant was precisely what you said:
- the new behaviour could not suddenly wreck any *current*, working,
compliant programs - since it'd be an opt-in attribute, and
- if one deliberately *added* said attribute but also stashed a
reference to an object for which it was declared they would not, the
program might compile, but it's on the programmer's head if the
optimisation process bites them, as doing so would be UB.
--
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/CACGiwhF_PGSqbfROx5tvxDBj0nsTpao3kOKqSGzpsKmTDwTjTQ%40mail.gmail.com.
--001a1147284e8f7fac053b1d3863
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On S=
at, Aug 27, 2016 at 11:48 PM, Nicol Bolas <span dir=3D"ltr"><<a href=3D"=
mailto:jmckesson@gmail.com" target=3D"_blank">jmckesson@gmail.com</a>></=
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"><span class=
=3D""></span><br><div>Hmm. At first, I didn't like the idea of it being=
merely a hint to the optimizer. When a destructor gets called is an observ=
able side-effect for any code where we would care to use such a thing. So i=
t should be something you could rely on.<br><br>After thinking about it for=
a bit however, making it a hint does solve a number of issues.<br></div></=
div></blockquote><div><br></div><div>Heh, I thought I was just inferring wh=
at you meant, but instead I came up with a new idea. That was unexpectedly =
useful! The rest of what you said is a good (probably better than I could&#=
39;ve written) outline of what I was thinking. So thanks! Although:<br><br>=
=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bo=
rder-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><spa=
n class=3D""><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>That said, I wonder how likely this is, given that by my understandin=
g, we're far into GC territory. But as a non-binding hint to the compil=
er that wouldn't affect semantics of well-formed programs, maybe it'=
;s not that outlandish at all... we have several of those already.<br></div=
></blockquote></span><div><br>But it would affect the semantics of well-for=
med programs. See my tuple example above; if `T t` had been annotated with =
the attribute, then it would make use of `tpl` without the use of `t` undef=
ined behavior. That's part of the promise you make when you use [[eager=
-destruct]] or whatever we call it.<br><br>It's no different from [[nor=
eturn]] in that regard; if such a function ever actually <i>returns</i>, yo=
u provoke UB.<br></div></div><span class=3D"">
<p></p>
</span></blockquote><div>Not sure if this was an imprecise choice of words =
on my part. But what I really meant was precisely what you said:<br><ul><li=
>the new behaviour could not suddenly wreck any <i>current</i>, working, co=
mpliant programs - since it'd be an opt-in attribute, and<br></li></ul>=
<ul><li>if one deliberately <i>added</i> said attribute but also stashed a =
reference to an object for which it was declared they would not, the progra=
m might compile, but it's on the programmer's head if=C2=A0 the opt=
imisation process bites them, as doing so would be UB.</li></ul><p><br></p>=
</div></div></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/CACGiwhF_PGSqbfROx5tvxDBj0nsTpao3kOKq=
SGzpsKmTDwTjTQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CACGiwhF_PGSqbfRO=
x5tvxDBj0nsTpao3kOKqSGzpsKmTDwTjTQ%40mail.gmail.com</a>.<br />
--001a1147284e8f7fac053b1d3863--
.
Author: jsphadetula@gmail.com
Date: Sun, 28 Aug 2016 09:58:56 +0000 (UTC)
Raw View
------=_Part_3662_706498864.1472378336052
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<some_syntax> varName;
what if <some_syntax>=C2=A0is explicitly applied on the intended last use o=
f varName after which any reference to varName will be treated as compile t=
ime error=20
in summary make <some_syntax>=C2=A0end the scope of varName even before the=
end of the current scope
Get Outlook for Android
On Sun, Aug 28, 2016 at 9:06 AM +0100, "D. B." <db0451@gmail.com> wrote:
On Sat, Aug 27, 2016 at 11:48 PM, Nicol Bolas <jmckesson@gmail.com> wrote:
Hmm. At first, I didn't like the idea of it being merely a hint to the opti=
mizer. When a destructor gets called is an observable side-effect for any c=
ode where we would care to use such a thing. So it should be something you =
could rely on.
After thinking about it for a bit however, making it a hint does solve a nu=
mber of issues.
Heh, I thought I was just inferring what you meant, but instead I came up w=
ith a new idea. That was unexpectedly useful! The rest of what you said is =
a good (probably better than I could've written) outline of what I was thin=
king. So thanks! Although:
=C2=A0That said, I wonder how likely this is, given that by my understandin=
g, we're far into GC territory. But as a non-binding hint to the compiler t=
hat wouldn't affect semantics of well-formed programs, maybe it's not that =
outlandish at all... we have several of those already.
But it would affect the semantics of well-formed programs. See my tuple exa=
mple above; if `T t` had been annotated with the attribute, then it would m=
ake use of `tpl` without the use of `t` undefined behavior. That's part of =
the promise you make when you use [[eager-destruct]] or whatever we call it=
..
It's no different from [[noreturn]] in that regard; if such a function ever=
actually returns, you provoke UB.
Not sure if this was an imprecise choice of words on my part. But what I re=
ally meant was precisely what you said:
the new behaviour could not suddenly wreck any current, working, compliant =
programs - since it'd be an opt-in attribute, and
if one deliberately added said attribute but also stashed a reference to an=
object for which it was declared they would not, the program might compile=
, but it's on the programmer's head if=C2=A0 the optimisation process bites=
them, as doing so would be UB.
--=20
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 e=
mail 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/CACGiwhF_PGSqbfROx5tvxDBj0nsTpao3kOKqSGzpsKmTDwT=
jTQ%40mail.gmail.com.
--=20
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 e=
mail 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/997FEFE7601FB061.100935c7-c671-4405-9c66-7452225=
5c54e%40mail.outlook.com.
------=_Part_3662_706498864.1472378336052
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<html><head></head><body><p dir=3D"auto"><br>
<some_syntax> varName;</p>
<p dir=3D"auto">what if <some_syntax> is explicitly applied on t=
he intended last use of varName after which any reference to varName will b=
e treated as compile time error </p>
<p dir=3D"auto">in summary make <some_syntax> end the scope of v=
arName even before the end of the current scope</p>
<p dir=3D"auto">Get <a href=3D"https://aka.ms/ghei36">Outlook for Android</=
a><br>
</p>
<br><br><br>
<div class=3D"gmail_quote">On Sun, Aug 28, 2016 at 9:06 AM +0100, "D. B." <=
span dir=3D"ltr"><<a href=3D"mailto:db0451@gmail.com" target=3D"_blank">=
db0451@gmail.com</a>></span> wrote:<br>
<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">
<div dir=3D"3D"ltr"">
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On S=
at, Aug 27, 2016 at 11:48 PM, Nicol Bolas <span dir=3D"ltr"><<a href=3D"=
mailto:jmckesson@gmail.com" target=3D"_blank">jmckesson@gmail.com</a>></=
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"><span class=
=3D""></span><br><div>Hmm. At first, I didn't like the idea of it being mer=
ely a hint to the optimizer. When a destructor gets called is an observable=
side-effect for any code where we would care to use such a thing. So it sh=
ould be something you could rely on.<br><br>After thinking about it for a b=
it however, making it a hint does solve a number of issues.<br></div></div>=
</blockquote><div><br></div><div>Heh, I thought I was just inferring what y=
ou meant, but instead I came up with a new idea. That was unexpectedly usef=
ul! The rest of what you said is a good (probably better than I could've wr=
itten) outline of what I was thinking. So thanks! Although:<br><br> </=
div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-lef=
t:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><span class=
=3D""><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></div>T=
hat said, I wonder how likely this is, given that by my understanding, we'r=
e far into GC territory. But as a non-binding hint to the compiler that wou=
ldn't affect semantics of well-formed programs, maybe it's not that outland=
ish at all... we have several of those already.<br></div></blockquote></spa=
n><div><br>But it would affect the semantics of well-formed programs. See m=
y tuple example above; if `T t` had been annotated with the attribute, then=
it would make use of `tpl` without the use of `t` undefined behavior. That=
's part of the promise you make when you use [[eager-destruct]] or whatever=
we call it.<br><br>It's no different from [[noreturn]] in that regard; if =
such a function ever actually <i>returns</i>, you provoke UB.<br></div></di=
v><span class=3D"">
<p></p>
</span></blockquote><div>Not sure if this was an imprecise choice of words =
on my part. But what I really meant was precisely what you said:<br><ul><li=
>the new behaviour could not suddenly wreck any <i>current</i>, working, co=
mpliant programs - since it'd be an opt-in attribute, and<br></li></ul><ul>=
<li>if one deliberately <i>added</i> said attribute but also stashed a refe=
rence to an object for which it was declared they would not, the program mi=
ght compile, but it's on the programmer's head if the optimisation pr=
ocess bites them, as doing so would be UB.</li></ul><p><br></p></div></div>=
</div></div>
<p></p>
-- <br>
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" 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/CACGiwhF_PGSqbfROx5tvxDBj0nsTpao3kOKq=
SGzpsKmTDwTjTQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CACGiwhF_PGSq=
bfROx5tvxDBj0nsTpao3kOKqSGzpsKmTDwTjTQ%40mail.gmail.com</a>.<br>
</div>
</blockquote>
</div>
</body></html>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/997FEFE7601FB061.100935c7-c671-4405-9=
c66-74522255c54e%40mail.outlook.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/997FEFE7601FB=
061.100935c7-c671-4405-9c66-74522255c54e%40mail.outlook.com</a>.<br />
------=_Part_3662_706498864.1472378336052--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sun, 28 Aug 2016 08:38:38 -0700 (PDT)
Raw View
------=_Part_3402_705376904.1472398718723
Content-Type: multipart/alternative;
boundary="----=_Part_3403_1952452395.1472398718724"
------=_Part_3403_1952452395.1472398718724
Content-Type: text/plain; charset=UTF-8
On Sunday, August 28, 2016 at 5:58:58 AM UTC-4, Olanrewaju Adetula wrote:
>
>
> <some_syntax> varName;
>
> what if <some_syntax> is explicitly applied on the intended last use of
> varName after which any reference to varName will be treated as compile
> time error
>
> in summary make <some_syntax> end the scope of varName even before the end
> of the current scope
>
The OP explicitly did not want that; he wants the compiler to figure it out
for itself, so that he doesn't have to clutter his code up with premature
destruction calls.
And there are already other ideas, as Matt suggested, for manually ending
the lifetime of an automatic variable.
--
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/c6ac3d0d-e50f-49e9-8dbe-26e8b73dc43b%40isocpp.org.
------=_Part_3403_1952452395.1472398718724
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Sunday, August 28, 2016 at 5:58:58 AM UTC-4, Olanrewaju=
Adetula wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-=
left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div><p dir=3D"=
auto"><br>
<some_syntax> varName;</p>
<p dir=3D"auto">what if <some_syntax>=C2=A0is explicitly applied on t=
he intended last use of varName after which any reference to varName will b=
e treated as compile time error </p>
<p dir=3D"auto">in summary make <some_syntax>=C2=A0end the scope of v=
arName even before the end of the current scope</p></div></blockquote><div>=
<br></div>The OP explicitly did not want that; he wants the compiler to fig=
ure it out for itself, so that he doesn't have to clutter his code up w=
ith premature destruction calls.<br><br>And there are already other ideas, =
as Matt suggested, for manually ending the lifetime of an automatic variabl=
e.<br></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/c6ac3d0d-e50f-49e9-8dbe-26e8b73dc43b%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/c6ac3d0d-e50f-49e9-8dbe-26e8b73dc43b=
%40isocpp.org</a>.<br />
------=_Part_3403_1952452395.1472398718724--
------=_Part_3402_705376904.1472398718723--
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Mon, 29 Aug 2016 11:04:41 -0400
Raw View
On 2016-08-24 14:51, nicolas.capens@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.
> [...]
General follow-up... I'm not sure I'm in favor of this proposal in
general, but I don't see it as feasible to make it a type property. You
are almost inevitably going to have cases where the feature needs to be
controlled on a per-variable basis, and having to produce duplicate
types (and convert between them!) is not practical, not to mention that
you may want to use it on types outside your control. (You mention
matrices a lot; well, what if I'm using Eigen matrices and want this?)
And then it occurred to me... we have the `register` keyword just
sitting there. And you keep referring to register allocation of
scalars... it seems that the old meaning of `register` is almost exactly
what you want.
It may also make sense to make it UB to take and retain a reference to
any `register` variable, including references to members of the same. If
we *really* wanted to be safe, we could make `register` a qualifier
(i.e. allow its use on function parameters) and make it *ill-formed* to
take a (non-`register`) reference to a `register` variable. This way,
you could still pass such a variable by reference to a function, but the
function would not be allowed to retain that reference. (This obviously
implies that no global variable may be `register` qualified, and the
presence of a `register` qualified member implies that the containing
object may only be used as a `register` variable itself.) This would
require much more extensive API modification for the feature to be
widely used, but the added safety might be worth it.
In fact, I can see some other potential (though probably breaking) uses
for such a feature. For example, std::string::data() could return `char*
register` instead of plain `char*` to indicate to callers that they may
not retain the returned pointer. (Maybe this could be a feature for STL2...)
--
Matthew
--
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/57C44F09.4010901%40gmail.com.
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Mon, 29 Aug 2016 11:11:26 -0400
Raw View
On 2016-08-26 17:23, Nicolas Capens wrote:
> On Wed, Aug 24, 2016 at 6:00 PM, Matt Calabrese wrote:
>> I'm sorry if I sound overly negative here, but the problems of this are
>> already well understood. For any kind of early destruction in a language
>> like C++, users would need to be explicit, and that's not bad in this case.
>> I genuinely do believe that something similar to this is worthwhile, but
>> your particular approach is unrealistic (I think specifically that
>> destructive-move would solve a lot of problems with the language and
>> library as it is today).
>
> I'd like to avoid getting sidetracked too much, but remind me again what
> destructive-move would solve that can't be done by overloading the
> assignment operator?
Destructive move a.k.a. relocation solves the problem of having to
maintain invariants in an object that is about to be destroyed anyway.
Consider for example your large matrix, with the invariant that its
storage is always allocated. In order to move construct an instance, you
must first allocate memory, then exchange the new memory with the
instance being moved from, so that the moved-from instance remains in a
valid state.
With relocation, you *know* that the old instance is being destroyed
anyway, so you can just take possession of its memory instead without
any new allocations.
--
Matthew
--
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/57C4509E.4050107%40gmail.com.
.
Author: Nicolas Capens <nicolas.capens@gmail.com>
Date: Mon, 29 Aug 2016 15:22:30 +0000
Raw View
--94eb2c112468597c00053b376ff2
Content-Type: text/plain; charset=UTF-8
On Wed, Aug 24, 2016 at 6:05 PM, Nicol Bolas <jmckesson@gmail.com> 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.
Anyway, making the destruction happen in a single, well-defined place can
be done by using the last "local" use of the object. It's also the most bug
prone, but if determinism is a necessity, then this is a feasible starting
point. It's not clear to me though that determinism is necessary. We don't
ask compilers to free up registers in a determinable way either. Anywhere
between the last conservative use and the end of the scope is valid. For my
use cases of eager destruction that's acceptable as well. I'd just like
make sure that compilers aren't going to be overly conservative.
> The ability to execute the destructor and simultaneously prevent the
> compiler from doing so is something that can be discussed and debated. But
> as Matt said, it would be explicit at the point of use, not implicitly
> built into the type. The code that wants to change the default behavior,
> which is the code that gains certain responsibilities by doing so, is the
> code *using* the object, not the code *defining* it.
>
First of all, that doesn't solve my use cases
<https://groups.google.com/a/isocpp.org/forum/#!msg/std-proposals/IUxA4cx8yHc/yKNqKl8hDgAJ>.
And secondly I can already do that today using a method to free up the
resources held by the object and being careful that the destructor doesn't
attempt to free them again. If there's still value in your feature that I
might be missing, fine, feel free to discuss it elsewhere.
> Putting it in the type is simply the wrong place for it. It's the code
> that needs the optimization who should be responsible for invoking this
> behavior.
>
> Anyway, for the use cases that I envision, the annotation at destructor
>> declaration is appropriate. For example say I need a huge matrix to
>> temporarily store some intermediate results. I could use "double
>> matrix[10000][10000];" and rely on the compiler's optimizations to use the
>> memory for other purposes as soon as I'm done with this matrix. But it's
>> simply not going to fit on the stack. So instead I'll use an object with a
>> pointer to heap memory. But now it only gets freed when it goes out of
>> scope.
>>
>
> No, it gets freed when you want it to be freed. Observe:
>
> auto heap_allocation = std::make_unique<T>(...);
>
> //use the object
>
> heap_allocation.reset();
>
> See? it's been freed after the last use.
>
> This way, you don't have to play games of wondering exactly when the
> allocation is destroyed. It's destroyed when you *destroy it*.
>
I don't want to manually destroy it. That's a critical part of the feature
I'm proposing. It needs to call the destructor automatically, just like
today for local objects, but call it more eagerly than at the end of the
scope so we get some optimization benefits without programmer involvement.
The only room for debate is whether we aggressively call the destructor at
the last local use, or require it to be conservative, or something in
between.
> 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?
There are some objects, some, not all of them, that could be treated to be
self-contained just like a register so that the compiler is free to
optimize their lifetime to something shorter than their scope.
> 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.
> Even with that, you might think that it's okay to annotate types that
>>> contain no logical relationships to objects that it does not own. For
>>> instance, something that just contains an int or a unique_ptr to some
>>> object with no relationships, etc. The problem is, even in these cases,
>>> there is nothing stopping some *other* object from storing a pointer or
>>> reference to an instance of your
>>> automatically-prematurely-destructible-type. If someone *does* hold such a
>>> reference and your annotated type is "no longer used", then the object that
>>> refers to it will now have a dangling reference. Point being, your
>>> annotation cannot be at the type level.
>>>
>>
>> This issue is not very different from still having a reference to a local
>> variable after it has gone out of scope. C++ is inherently unsafe, and you
>> simply need to know what you're doing. With lazy destruction, don't use any
>> references to the object after it has gone out of scope. With eager
>> destruction, don't use any references to the object after its last use. A
>> compiler warning could help prevent people from shooting themselves in the
>> foot in both cases.
>>
>
> What would trigger such a warning? Passing a variable of such a type as a
> reference to someone else? Because that's all the compiler can know: that a
> reference or pointer was passed to some function. It has no idea if that
> function retains that value or not, or when it is expected to relinquish it.
>
> You'd need serious static analysis to avoid a litany of false positives.
>
Indeed. This is the kind of information that will determine whether we can
go with the conservative option or need the more aggressive one. But I'm
not fully convinced that this analysis is hard to do. The equivalent
problem for registers is called interprocedural register allocation, and I
was able to find research papers on it dating back to the early 80's. And
knowing whether a function retained a reference is in fact easier than
knowing which registers it uses.
--
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/CAE7XuEXEV%3DxKW_g-1h1MFbg-3Fya83xkcoqGePvPbBPMTXPamA%40mail.gmail.com.
--94eb2c112468597c00053b376ff2
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On W=
ed, Aug 24, 2016 at 6:05 PM, Nicol Bolas <span dir=3D"ltr"><<a href=3D"m=
ailto:jmckesson@gmail.com" target=3D"_blank">jmckesson@gmail.com</a>></s=
pan> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex=
;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><span>On Wed=
nesday, August 24, 2016 at 5:17:26 PM UTC-4, <a href=3D"mailto:nicolas...@g=
mail.com" target=3D"_blank">nicolas...@gmail.com</a> wrote:<blockquote clas=
s=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc =
solid;padding-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" sty=
le=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1e=
x"><div dir=3D"ltr"><div><div class=3D"gmail_quote">On Wed, Aug 24, 2016 at=
11:51 AM, <span dir=3D"ltr"><<a rel=3D"nofollow">nicolas...@gmail.com<=
/a>></span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:=
0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><d=
iv>Hi all,</div><div><br></div>I'd like to propose a new kind of destru=
ctor that gets called after a local object's last use, instead of at th=
e end of its scope.<div><br></div><div>The use of this would be to free res=
ources 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.</div><div><br=
></div><div>Currently such optimization can only be achieved by explicitly =
releasing the resources, which is inconvenient, bug prone, and reduces read=
ability. Limiting the scope with extra braces or by putting the operations =
in a subroutine also often isn't a desirable workaround. Note that comp=
ilers have been doing liveness analysis for register allocation and stack c=
ompaction 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.</div><div><span style=3D"line-height:17px"><br></span></div><div>The =
s<span style=3D"line-height:17px">yntax for this could be an annotation of =
the destructor declaration with a keyword, symbol, or attribute. For exampl=
e, "auto ~Object();", "volatile ~Object();", "~~Ob=
ject();", or "[[eager]] ~Object();".</span></div><div><span =
style=3D"line-height:17px"><br></span></div><div><span style=3D"line-height=
:17px">Thoughts?</span></div></div></blockquote><div><br></div><div>While I=
would like C++ to eventually get a way to do the equivalent of this in som=
e form (more generally, I want destructive move, which is related to this e=
ven though it may not be immediately obvious),</div></div></div></div></blo=
ckquote><div><br></div><div>Yes, a destructive assignment could count as a =
last use of its previous value and call the destructor that I'm proposi=
ng. I'd also like it to be called after the last use as a source argume=
nt too though.</div><div>=C2=A0</div><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"><div><div class=3D"gmail_quote"><div>I do not think that=
the appropriate place to notate the premature destruction is on the destru=
ctor declaration. Instead, I believe it needs to be explicit at the usage-s=
ite. This is primarily because we are in a language where side-effects matt=
er.</div></div></div></div></blockquote><div><br></div><div>I wouldn't =
call it premature destruction. Eager instead of today's lazy destructio=
n at the end of the scope, seems like a better description to me.</div></di=
v></blockquote></span><div><br>Playing word games doesn't change the fa=
ct that the standard makes it clear that destruction of an automatic object=
happens in a single, well-defined place. Your proposal wants to *transpare=
ntly* change that location based on something in the type of that object.<b=
r></div></div></blockquote><div><br></div></div></div><div dir=3D"ltr"><div=
class=3D"gmail_extra"><div class=3D"gmail_quote"><div>It's not a word =
game. Premature anything is a bad thing and we shouldn't present this f=
eature to users that way. Lazy vs. eager is more neutral. Other suggestions=
welcome.</div><div><br></div><div>Anyway, making the destruction happen in=
a single, well-defined place can be done by using the last "local&quo=
t; use of the object. It's also the most bug prone, but if determinism =
is a necessity, then this is a feasible starting point. It's not clear =
to me though that determinism is necessary. We don't ask compilers to f=
ree up registers in a determinable way either. Anywhere between the last co=
nservative use and the end of the scope is valid. For my use cases of eager=
destruction that's acceptable as well. I'd just like make sure tha=
t compilers aren't going to be overly conservative.</div></div></div></=
div><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">=
<div>=C2=A0</div><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>The a=
bility to execute the destructor and simultaneously prevent the compiler fr=
om doing so is something that can be discussed and debated. But as Matt sai=
d, it would be explicit at the point of use, not implicitly built into the =
type. The code that wants to change the default behavior, which is the code=
that gains certain responsibilities by doing so, is the code <i>using</i> =
the object, not the code <i>defining</i> it.<br></div></div></blockquote><d=
iv><br></div><div>First of all, that doesn't solve <a href=3D"https://g=
roups.google.com/a/isocpp.org/forum/#!msg/std-proposals/IUxA4cx8yHc/yKNqKl8=
hDgAJ">my use cases</a>. And secondly I can already do that today using a m=
ethod to free up the resources held by the object and being careful that th=
e destructor doesn't attempt to free them again. If there's still v=
alue in your feature that I might be missing, fine, feel free to discuss it=
elsewhere.</div><div>=C2=A0</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>Putting it in the type is simply the wrong place for it. It&#=
39;s the code that needs the optimization who should be responsible for inv=
oking this behavior.<br><br></div><span><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></div><div>Anyway, for the use cases that I envi=
sion, the annotation at destructor declaration is appropriate. For example =
say I need a huge matrix to temporarily store some intermediate results. I =
could use "double matrix[10000][10000];" and rely on the compiler=
's optimizations to use the memory for other purposes as soon as I'=
m done with this matrix. But it's simply not going to fit on the stack.=
So instead I'll use an object with a pointer to heap memory. But now i=
t only gets freed when it goes out of scope.</div></div></blockquote></span=
><div><br>No, it gets freed when you want it to be freed. Observe:<br><br><=
div style=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><spa=
n style=3D"color:#008">auto</span><span style=3D"color:#000"> heap_allocati=
on </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> =
std</span><span style=3D"color:#660">::</span><span style=3D"color:#000">ma=
ke_unique</span><span style=3D"color:#660"><</span><span style=3D"color:=
#000">T</span><span style=3D"color:#660">>(...);</span><span style=3D"co=
lor:#000"><br><br></span><span style=3D"color:#800">//use the object</span>=
<span style=3D"color:#000"><br><br>heap_allocation</span><span style=3D"col=
or:#660">.</span><span style=3D"color:#000">reset</span><span style=3D"colo=
r:#660">();</span></div></code></div><br>See? it's been freed after the=
last use.<br><br>This way, you don't have to play games of wondering e=
xactly when the allocation is destroyed. It's destroyed when you <i>des=
troy it</i>.<br></div></div></blockquote><div><br></div><div>I don't wa=
nt to manually destroy it. That's a critical part of the feature I'=
m proposing. It needs to call the destructor automatically, just like today=
for local objects, but call it more eagerly than at the end of the scope s=
o we get some optimization benefits without programmer involvement. The onl=
y room for debate is whether we aggressively call the destructor at the las=
t local use, or require it to be conservative, or something in between.</di=
v><div>=C2=A0</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>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:<br><br><div style=3D"background-color:rgb(250,250,250);border-colo=
r:rgb(187,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=
">::</span><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:#66=
0">));</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=
automatic 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 o=
bject.<br></div></div></blockquote><div><br></div><div>Why? We don't qu=
estion whether a register is still in use or not, don't we? There are s=
ome objects, some, not all of them, that could be treated to be self-contai=
ned just like a register so that the compiler is free to optimize their lif=
etime to something shorter than their scope.</div><div>=C2=A0</div><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr"><div></div><span><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>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 t=
hat I want it's destructor to be called eagerly. If I don't want th=
at behavior I can simply use an equivalent class without eager destructor.<=
/div></div></blockquote></span><div><br>You've provided a very good rea=
son not to do this at all. We do not want to encourage the proliferation of=
types that differ <i>only</i> by the presence or absence of "eager de=
struction". We don't want `eager_unique_ptr` or `eager_ifstream` o=
r `eager_vector` or whatever.<br></div></div></blockquote><div><br></div><d=
iv>The way I envision this to be used you won't need such a prefix at a=
ll. It would just be Matrix, Int, or Streamer, like in <a href=3D"https://g=
roups.google.com/a/isocpp.org/forum/#!msg/std-proposals/IUxA4cx8yHc/yKNqKl8=
hDgAJ">my examples</a>. The framework they're part of is responsible of=
making sure they're self-contained objects and under normal circumstan=
ces can't be used incorrectly.</div><div>=C2=A0</div><blockquote class=
=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr"><div></div><span><blockquote class=3D"gmail_=
quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddi=
ng-left:1ex"><div dir=3D"ltr"><div> </div><blockquote class=3D"gmail_quote"=
style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-lef=
t:1ex"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div>Even with that=
, you might think that it's okay to annotate types that contain no logi=
cal relationships to objects that it does not own. For instance, something =
that just contains an int or a unique_ptr to some object with no relationsh=
ips, etc. The problem is, even in these cases, there is nothing stopping so=
me *other* object from storing a pointer or reference to an instance of you=
r automatically-prematurely-destructible-type. If someone *does* hold such =
a reference and your annotated type is "no longer used", then the=
object that refers to it will now have a dangling reference. Point being, =
your annotation cannot be at the type level.</div></div></div></div></block=
quote><div><br></div><div>This issue is not very different from still havin=
g a reference to a local variable after it has gone out of scope. C++ is in=
herently unsafe, and you simply need to know what you're doing. With la=
zy destruction, don't use any references to the object after it has gon=
e out of scope. With eager destruction, don't use any references to the=
object after its last use. A compiler warning could help prevent people fr=
om shooting themselves in the foot in both cases.</div></div></blockquote><=
/span><div dir=3D"ltr"><br>What would trigger such a warning? Passing a var=
iable of such a type as a reference to someone else? Because that's all=
the compiler can know: that a reference or pointer was passed to some func=
tion. It has no idea if that function retains that value or not, or when it=
is expected to relinquish it.<br><br>You'd need serious static analysi=
s to avoid a litany of false positives.</div></div></blockquote><div><br></=
div><div>Indeed. This is the kind of information that will determine whethe=
r we can go with the conservative option or need the more aggressive one. B=
ut I'm not fully convinced that this analysis is hard to do. The equiva=
lent problem for registers is called interprocedural register allocation, a=
nd I was able to find research papers on it dating back to the early 80'=
;s. And knowing whether a function retained a reference is in fact easier t=
han knowing which registers it uses.</div></div></div></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/CAE7XuEXEV%3DxKW_g-1h1MFbg-3Fya83xkco=
qGePvPbBPMTXPamA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAE7XuEXEV%3DxK=
W_g-1h1MFbg-3Fya83xkcoqGePvPbBPMTXPamA%40mail.gmail.com</a>.<br />
--94eb2c112468597c00053b376ff2--
.
Author: Nicolas Capens <nicolas.capens@gmail.com>
Date: Mon, 29 Aug 2016 17:02:30 +0000
Raw View
--001a1147b804f865ad053b38d47d
Content-Type: text/plain; charset=UTF-8
On Fri, Aug 26, 2016 at 5:46 PM Ren Industries <renindustries@gmail.com>
wrote:
> That in no way demonstrates it is similar to register allocation, which
> is, again, a QOI issue.
>
My apologies. The example omitted how the equivalent scalar code would have
its registers freed up for use by other variables after their last use. I
thought that would be sufficiently clear. Here's an illustration of that:
http://compilers.cs.ucla.edu/fernando/projects/puzzles/tutorial/. The end
of the live ranges corresponds to where I'd like the destructors of objects
to be called. Let me know if the similarities are still not obvious to you
and I'll create a more detailed side-by-side example if I find the time.
Anyway, yes, register allocation is a quality of implementation issue. One
that is enabled by the standard allowing for it because scalars having no
side-effects on destruction. I want to enable that same freedom of
optimization for objects that do have side-effects, by telling the compiler
that we don't care about these side-effects to happen at the end of the
variable's scope.
> It is not necessarily the case that a compiler need do that, and I can
> think of at least a few counter examples. For example, there are projects
> that output C++ to javascript or java, which have no notion of register
> allocation as you point to it. These "machines" are perfectly valid C++
> targets, yet have absolutely no notion of what you are talking about.
>
I realize that. But I shouldn't have to care if a compiler strictly needs
to do that today or not. I'm talking about adding a new feature to the
language, and this may involve adding some new implementation requirements.
If that causes some cross-compilers to no longer be able to support this
new version of C++ without some non-trivial effort, too bad. It's certainly
not my aim to make implementer's lives difficult, but I also don't want to
cripple or abandon the feature because of it.
Indeed, C++ supports a huge variety of applications. More than you know of,
> it seems.
>
You're talking about Emscripten and alike. That's implementation side. I
was talking about applications written in C++. You seemed to see no
practical uses for this feature, presumably because you hadn't encountered
such an application before. Did my trivial example clarify that manual
freeing of the resources is not acceptable, or do you still disagree?
> On Fri, Aug 26, 2016 at 3:21 PM, Nicolas Capens <nicolas.capens@gmail.com>
> wrote:
>
>> On Fri, Aug 26, 2016 at 1:16 PM, Ren Industries <renindustries@gmail.com>
>> wrote:
>>
>>> Why is it such a terrible imposition to require manual interaction to
>>> enforce this behavior? I don't buy your argument that it is similar to
>>> register allocation; that's a QOI not a standards issue.
>>>
>>
>> Consider this simple statement:
>>
>> x = a * b * c;
>>
>> Assume they're all scalars, and a, b, and c are no longer used after this
>> statement. That means liveness analysis will make their registers available
>> for other variables, without you having to worry about it. But if instead
>> these variables were huge matrices and you had to manually free their
>> storage to minimize memory consumption, then it would look something like
>> this:
>>
>> Matrix t = a * b;
>> a.~Matrix();
>> b.~Matrix();
>> x = t * c;
>> t.~Matrix();
>> c.~Matrix();
>>
>> Or if you wanted to do it with scopes:
>>
>> {
>> Matrix t;
>> {
>> Matrix a = ...;
>> Matrix b = ...;
>> t = a * b;
>> }
>> Matrix c = ...;
>> x = t * c;
>> }
>>
>> To me the original statement looks a whole lot easier to read and
>> maintain than the two workarounds. And this is just a trivial example! It
>> would become insane to do it for any realistic data processing code.
>>
>> Also I think that calling something a "terrible imposition" or not is
>> highly subjective. Many recent C++ features solve issues that already had
>> workarounds which some considered acceptable but were unworkable for
>> others. So please avoid being prejudiced by your own experience and having
>> no direct use for this yourself. C++ supports a huge variety of
>> applications.
>>
>> I hope the above example illustrates that this is very similar to
>> register allocation, and it's a standards issue that we don't get this
>> behavior today for non-scalar types.
>>
>>
>>> On Fri, Aug 26, 2016 at 1:05 PM, Nicolas Capens <
>>> nicolas.capens@gmail.com> wrote:
>>>
>>>>
>>>>
>>>> On Wed, Aug 24, 2016 at 4:22 PM Nevin Liber <nevin@eviloverlord.com>
>>>> wrote:
>>>>
>>>>> On 24 August 2016 at 15:16, <nicolas.capens@gmail.com> wrote:
>>>>>
>>>>>> The code would become littered with braces if you want to limit the
>>>>>> scope of each object to its miminal range,
>>>>>>
>>>>>
>>>>> I don't understand why you would want to do that. Could you elaborate?
>>>>>
>>>>
>>>> Certainly. I wrote down three practical use cases here
>>>> <https://groups.google.com/a/isocpp.org/forum/#!msg/std-proposals/IUxA4cx8yHc/yKNqKl8hDgAJ>
>>>> .
>>>>
>>>>
>>>>> And if the objects are truly independent and have no observable
>>>>> effect, can't a compiler do that under the as-if rule?
>>>>>
>>>>
>>>> The problem is that the objects I'm using do have side-effects, so the
>>>> compiler won't attempt to shorten their lifespan. But in my use cases the
>>>> side effects are "self-contained", i.e. you could treat them as scalars and
>>>> destruct them right after their last use.
>>>>
>>>>
>>>>> Also, if you wish to have a lifetime shorter than a scope for an
>>>>> object of type T, you can just use std::optional<T>.
>>>>>
>>>>
>>>> How would that work, without requiring manual actions to destruct it?
>>>>
>>>>
>>>>> Fortunately we don't, because today's compilers do liveness analysis
>>>>>> to optimize register allocation.
>>>>>>
>>>>>
>>>>> One of the huge benefits to C++ is that destruction happens at well
>>>>> defined times. This would break that.
>>>>>
>>>>
>>>> Yes, in many cases it will be preferable to keep the well defined
>>>> behavior of implicitly calling the destructor at the end of the variable's
>>>> scope. The opt-in feature I'm proposing should be used sparingly and
>>>> cautiously. But when used by a well written framework it should be
>>>> foolproof for the users of the framework, and offer them significant
>>>> benefits.
>>>>
>>>>
>>>>> --
>>>>> Nevin ":-)" Liber <mailto:nevin@eviloverlord.com> +1-847-691-1404
>>>>>
>>>>> --
>>>>> 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-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/CAGg_6%2BM3M43y_8jTg4mXce1sz7UQ5kzSkOVqL3F_nYEe-ogzNA%40mail.gmail.com
>>>>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAGg_6%2BM3M43y_8jTg4mXce1sz7UQ5kzSkOVqL3F_nYEe-ogzNA%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/CAE7XuEVobd1QW2jJYW-hGTLTPgQxRJM-QkL9jNovOkhaaoXQEw%40mail.gmail.com
>>>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAE7XuEVobd1QW2jJYW-hGTLTPgQxRJM-QkL9jNovOkhaaoXQEw%40mail.gmail.com?utm_medium=email&utm_source=footer>
>>>> .
>>>>
>>>
>>> --
>>> 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-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/CAMD6iD_8zsoqfYdUsY%2BQe_QNvzFsH4c9uUjNYzw5BRFiLQRE%2BQ%40mail.gmail.com
>>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAMD6iD_8zsoqfYdUsY%2BQe_QNvzFsH4c9uUjNYzw5BRFiLQRE%2BQ%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/CAE7XuEXAELWV5xFYABGNy%2Bc1vQxatD7JEDY%3DJst%3DC_wgyrwj0w%40mail.gmail.com.
--001a1147b804f865ad053b38d47d
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 Fri, Aug 26=
, 2016 at 5:46 PM Ren Industries <<a href=3D"mailto:renindustries@gmail.=
com">renindustries@gmail.com</a>> 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">That in no way demonstrates it is similar to regi=
ster allocation, which is, again, a QOI issue.</div></blockquote><div><br><=
/div><div>My apologies. The example omitted how the equivalent scalar code =
would have its registers freed up for use by other variables after their la=
st use. I thought that would be sufficiently clear. Here's an illustrat=
ion of that:=C2=A0<a href=3D"http://compilers.cs.ucla.edu/fernando/projects=
/puzzles/tutorial/">http://compilers.cs.ucla.edu/fernando/projects/puzzles/=
tutorial/</a>. The end of the live ranges corresponds to where I'd like=
the destructors of objects to be called. Let me know if the similarities a=
re still not obvious to you and I'll create a more detailed side-by-sid=
e example if I find the time.</div><div><br></div><div>Anyway, yes, registe=
r allocation is a quality of implementation issue. One that is enabled by t=
he standard allowing for it because scalars having no side-effects on destr=
uction. I want to enable that same freedom of optimization for objects that=
do have side-effects, by telling the compiler that we don't care about=
these side-effects to happen at the end of the variable's scope.</div>=
<div>=C2=A0</div><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">It is not =
necessarily the case that a compiler need do that, and I can think of at le=
ast a few counter examples. For example, there are projects that output C++=
to javascript or java, which have no notion of register allocation as you =
point to it. These "machines" are perfectly valid C++ targets, ye=
t have absolutely no notion of what you are talking about.</div></blockquot=
e><div><br></div><div>I realize that. But I shouldn't have to care if a=
compiler strictly needs to do that today or not. I'm talking about add=
ing a new feature to the language, and this may involve adding some new imp=
lementation requirements. If that causes some cross-compilers to no longer =
be able to support this new version of C++ without some non-trivial effort,=
too bad. It's certainly not my aim to make implementer's lives dif=
ficult, but I also don't want to cripple or abandon the feature because=
of it.</div><div><br></div><blockquote class=3D"gmail_quote" style=3D"marg=
in:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"=
><div>Indeed, C++ supports a huge variety of applications. More than you kn=
ow of, it seems.</div></div></blockquote><div><br></div><div>You're tal=
king about Emscripten and alike. That's implementation side. I was talk=
ing about applications written in C++. You seemed to see no practical uses =
for this feature, presumably because you hadn't encountered such an app=
lication before. Did my trivial example clarify that manual freeing of the =
resources is not acceptable, or do you still disagree?</div><div>=C2=A0</di=
v><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:=
1px #ccc solid;padding-left:1ex"><div class=3D"gmail_extra"><div class=3D"g=
mail_quote">On Fri, Aug 26, 2016 at 3:21 PM, Nicolas Capens <span dir=3D"lt=
r"><<a href=3D"mailto:nicolas.capens@gmail.com" target=3D"_blank">nicola=
s.capens@gmail.com</a>></span> wrote:<br><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"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><spa=
n>On Fri, Aug 26, 2016 at 1:16 PM, Ren Industries <span dir=3D"ltr"><<a =
href=3D"mailto:renindustries@gmail.com" target=3D"_blank">renindustries@gma=
il.com</a>></span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"=
margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-lef=
t:1ex"><div dir=3D"ltr">Why is it such a terrible imposition to require man=
ual interaction to enforce this behavior? I don't buy your argument tha=
t it is similar to register allocation; that's a QOI not a standards is=
sue.</div></blockquote><div><br></div></span><div>Consider this simple stat=
ement:</div><div><br></div><div>=C2=A0 =C2=A0 x =3D a * b * c;</div><div><b=
r></div><div>Assume they're all scalars, and a, b, and c are no longer =
used after this statement. That means liveness analysis will make their reg=
isters available for other variables, without you having to worry about it.=
But if instead these variables were huge matrices and you had to manually =
free their storage to minimize memory consumption, then it would look somet=
hing like this:</div><div><br></div><div>=C2=A0 =C2=A0 Matrix t =3D a * b;<=
/div><div>=C2=A0 =C2=A0 a.~Matrix();</div><div>=C2=A0 =C2=A0 b.~Matrix();</=
div><div>=C2=A0 =C2=A0 x =3D t * c;</div><div>=C2=A0 =C2=A0 t.~Matrix();</d=
iv><div>=C2=A0 =C2=A0 c.~Matrix();</div><div><br></div><div>Or if you wante=
d to do it with scopes:</div><div><br></div><div>=C2=A0 =C2=A0 {</div><div>=
=C2=A0 =C2=A0 Matrix t;</div><div>=C2=A0 =C2=A0 {</div><div>=C2=A0 =C2=A0 M=
atrix a =3D ...;</div><div>=C2=A0 =C2=A0 Matrix b =3D ...;</div><div>=C2=A0=
=C2=A0 t =3D a * b;</div><div>=C2=A0 =C2=A0 }</div><div>=C2=A0 =C2=A0 Matr=
ix c =3D ...;<br></div><div>=C2=A0 =C2=A0 x =3D t * c;</div><div>=C2=A0 =C2=
=A0 }</div><div><br></div><div>To me the original statement looks a whole l=
ot easier to read and maintain than the two workarounds. And this is just a=
trivial example! It would become insane to do it for any realistic data pr=
ocessing code.</div><div><br></div><div>Also I think that calling something=
a "terrible imposition" or not is highly subjective. Many recent=
C++ features solve issues that already had workarounds which some consider=
ed acceptable but were unworkable for others. So please avoid being prejudi=
ced by your own experience and having no direct use for this yourself. C++ =
supports a huge variety of applications.</div><div><br></div><div>I hope th=
e above example illustrates that this is very similar to register allocatio=
n, and it's a standards issue that we don't get this behavior today=
for non-scalar types.</div><div>=C2=A0</div><blockquote class=3D"gmail_quo=
te" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204=
);padding-left:1ex"><div><div><div class=3D"gmail_extra"><div class=3D"gmai=
l_quote"><div><div>On Fri, Aug 26, 2016 at 1:05 PM, Nicolas Capens <span di=
r=3D"ltr"><<a href=3D"mailto:nicolas.capens@gmail.com" target=3D"_blank"=
>nicolas.capens@gmail.com</a>></span> wrote:<br></div></div><blockquote =
class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px sol=
id rgb(204,204,204);padding-left:1ex"><div><div><div dir=3D"ltr"><br><br><d=
iv class=3D"gmail_quote"><span><div dir=3D"ltr">On Wed, Aug 24, 2016 at 4:2=
2 PM Nevin Liber <<a href=3D"mailto:nevin@eviloverlord.com" target=3D"_b=
lank">nevin@eviloverlord.com</a>> wrote:<br></div><blockquote class=3D"g=
mail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204=
,204,204);padding-left:1ex"><div dir=3D"ltr">On 24 August 2016 at 15:16, <=
span dir=3D"ltr"><<a href=3D"mailto:nicolas.capens@gmail.com" target=3D"=
_blank">nicolas.capens@gmail.com</a>></span> wrote:<br></div><div dir=3D=
"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><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"><div dir=3D"ltr"><div>The code would bec=
ome littered with braces if you want to limit the scope of each object to i=
ts miminal range,</div></div></blockquote><div><br></div></div></div></div>=
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div=
>I don't understand why you would want to do that.=C2=A0 Could you elab=
orate?</div></div></div></div></blockquote><div><br></div></span><div>Certa=
inly. I wrote down three practical use cases <a href=3D"https://groups.goog=
le.com/a/isocpp.org/forum/#!msg/std-proposals/IUxA4cx8yHc/yKNqKl8hDgAJ" tar=
get=3D"_blank">here</a>.</div><span><div>=C2=A0</div><blockquote class=3D"g=
mail_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 class=3D"gmail_extra"><di=
v class=3D"gmail_quote"><div>And if the objects are truly independent and h=
ave no observable effect, can't a compiler do that under the as-if rule=
?</div></div></div></div></blockquote><div><br></div></span><div>The proble=
m is that the objects I'm using do have side-effects, so the compiler w=
on't attempt to shorten their lifespan. But in my use cases the side ef=
fects are "self-contained", i.e. you could treat them as scalars =
and destruct them right after their last use.</div><span><div>=C2=A0</div><=
blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-l=
eft:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div clas=
s=3D"gmail_extra"><div class=3D"gmail_quote"><div>Also, if you wish to have=
a lifetime shorter than a scope for an object of type T, you can just use =
std::optional<T>.</div></div></div></div></blockquote><div><br></div>=
</span><div>How would that work, without requiring manual actions to destru=
ct it?</div><span><div>=C2=A0</div><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 class=3D"gmail_extra"><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>Fortunately we don't, because today's compilers do liveness ana=
lysis to optimize register allocation.</div></div></blockquote><div><br></d=
iv></div></div></div><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=
=3D"gmail_quote"><div>One of the huge benefits to C++ is that destruction h=
appens at well defined times.=C2=A0 This would break that.</div></div></div=
></div></blockquote><div><br></div></span><div>Yes, in many cases it will b=
e preferable to keep the well defined behavior of implicitly calling the de=
structor at the end of the variable's scope. The opt-in feature I'm=
proposing should be used sparingly and cautiously. But when used by a well=
written framework it should be foolproof for the users of the framework, a=
nd offer them significant benefits.</div><div>=C2=A0</div><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"><span><div dir=3D"ltr"><div class=3D"gmail=
_extra">-- <br><div data-smartmail=3D"gmail_signature"><div dir=3D"ltr"><di=
v><div dir=3D"ltr"><div>=C2=A0Nevin ":-)" Liber=C2=A0 <mailto:=
<a href=3D"mailto:nevin@eviloverlord.com" target=3D"_blank">nevin@eviloverl=
ord.com</a>> =C2=A0<a href=3D"tel:%2B1-847-691-1404" value=3D"+184769114=
04" target=3D"_blank">+1-847-691-1404</a></div></div></div></div></div>
</div></div>
<p></p>
-- <br></span>
You received this message because you are subscribed to a topic in the Goog=
le Groups "ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/IUxA4cx8yHc/unsubscribe" target=3D"_blan=
k">https://groups.google.com/a/isocpp.org/d/topic/std-proposals/IUxA4cx8yHc=
/unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a href=
=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_blank">std-prop=
osals+unsubscribe@isocpp.org</a>.<span><br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">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/CAGg_6%2BM3M43y_8jTg4mXce1sz7UQ5kzSkO=
VqL3F_nYEe-ogzNA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r" target=3D"_blank">https://groups.google.com/a/isocpp.org/d/msgid/std-pro=
posals/CAGg_6%2BM3M43y_8jTg4mXce1sz7UQ5kzSkOVqL3F_nYEe-ogzNA%40mail.gmail.c=
om</a>.<br>
</span></blockquote></div></div></div></div><span>
<p></p>
-- <br><span>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br></span>
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" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<span><br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></span></span>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAE7XuEVobd1QW2jJYW-hGTLTPgQxRJM-QkL9=
jNovOkhaaoXQEw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
target=3D"_blank">https://groups.google.com/a/isocpp.org/d/msgid/std-propo=
sals/CAE7XuEVobd1QW2jJYW-hGTLTPgQxRJM-QkL9jNovOkhaaoXQEw%40mail.gmail.com</=
a>.<br>
</blockquote></div><br></div><span>
<p></p>
-- <br>
You received this message because you are subscribed to a topic in the Goog=
le Groups "ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/IUxA4cx8yHc/unsubscribe" target=3D"_blan=
k">https://groups.google.com/a/isocpp.org/d/topic/std-proposals/IUxA4cx8yHc=
/unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a href=
=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_blank">std-prop=
osals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></span></div></div=
>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAMD6iD_8zsoqfYdUsY%2BQe_QNvzFsH4c9uU=
jNYzw5BRFiLQRE%2BQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoo=
ter" target=3D"_blank">https://groups.google.com/a/isocpp.org/d/msgid/std-p=
roposals/CAMD6iD_8zsoqfYdUsY%2BQe_QNvzFsH4c9uUjNYzw5BRFiLQRE%2BQ%40mail.gma=
il.com</a>.<br>
</blockquote></div><br></div></div>
</blockquote></div><br></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" 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/CAE7XuEXAELWV5xFYABGNy%2Bc1vQxatD7JED=
Y%3DJst%3DC_wgyrwj0w%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAE7XuEXAEL=
WV5xFYABGNy%2Bc1vQxatD7JEDY%3DJst%3DC_wgyrwj0w%40mail.gmail.com</a>.<br />
--001a1147b804f865ad053b38d47d--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 29 Aug 2016 11:46:36 -0700 (PDT)
Raw View
------=_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"><<a href=3D"javascript:" target=3D"_blank" gdf-obfusc=
ated-mailto=3D"MkuhA1TMEQAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#=
39;javascript:';return true;" onclick=3D"this.href=3D'javascript:&#=
39;;return true;">jmck...@gmail.com</a>></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"><<a rel=3D"nofollow">nicolas...@gmail.com</a>></=
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'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.<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'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'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'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, "=
auto ~Object();", "volatile ~Object();", "~~Object();&q=
uot;, or "[[eager]] ~Object();".</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'm proposing. I'=
;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't call it p=
remature destruction. Eager instead of today'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'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's not a word game. Premature anything is a b=
ad thing and we shouldn'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 "playing word games" 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'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't question w=
hether a register is still in use or not, don't we?</div></div></div></=
div></div></blockquote><div><br>I don'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'd like it to be destroyed e=
agerly, and not just for this one but for every instance. It's a proper=
ty 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 wi=
thout eager destructor.</div></div></blockquote></span><div><br>You'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 "eager destruction". We don'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'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'https://groups.google.com/a/isocpp.org/forum/#!msg/s=
td-proposals/IUxA4cx8yHc/yKNqKl8hDgAJ';return true;" onclick=3D"this.hr=
ef=3D'https://groups.google.com/a/isocpp.org/forum/#!msg/std-proposals/=
IUxA4cx8yHc/yKNqKl8hDgAJ';return true;">my examples</a>. The framework =
they're part of is responsible of making sure they're self-containe=
d objects and under normal circumstances can't be used incorrectly.</di=
v></div></div></div></div></blockquote><div><br>Your interface cannot stop =
people from using the object "incorrectly". 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 "under normal circumstances" 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`'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'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'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">&</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">&</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'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'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'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 "incorrect" 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" 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--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 29 Aug 2016 11:52:57 -0700 (PDT)
Raw View
------=_Part_4297_1477428899.1472496777227
Content-Type: multipart/alternative;
boundary="----=_Part_4298_1758960806.1472496777227"
------=_Part_4298_1758960806.1472496777227
Content-Type: text/plain; charset=UTF-8
On Monday, August 29, 2016 at 11:04:49 AM UTC-4, Matthew Woehlke wrote:
>
> On 2016-08-24 14:51, nicolas...@gmail.com <javascript:> 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.
> > [...]
>
> General follow-up... I'm not sure I'm in favor of this proposal in
> general, but I don't see it as feasible to make it a type property. You
> are almost inevitably going to have cases where the feature needs to be
> controlled on a per-variable basis, and having to produce duplicate
> types (and convert between them!) is not practical, not to mention that
> you may want to use it on types outside your control. (You mention
> matrices a lot; well, what if I'm using Eigen matrices and want this?)
>
> And then it occurred to me... we have the `register` keyword just
> sitting there. And you keep referring to register allocation of
> scalars... it seems that the old meaning of `register` is almost exactly
> what you want.
>
> It may also make sense to make it UB to take and retain a reference to
> any `register` variable, including references to members of the same. If
> we *really* wanted to be safe, we could make `register` a qualifier
> (i.e. allow its use on function parameters) and make it *ill-formed* to
> take a (non-`register`) reference to a `register` variable.
So now you want `const virtual register` qualifiers on variables? Do we
*really* need that?
The attribute approach seems so much cleaner.
--
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/3e6d3a32-714f-4de5-8f2a-fdba73286e9c%40isocpp.org.
------=_Part_4298_1758960806.1472496777227
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Monday, August 29, 2016 at 11:04:49 AM UTC-4, M=
atthew Woehlke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2016-0=
8-24 14:51, <a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=
=3D"k4lJV1rLEQAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascri=
pt:';return true;" onclick=3D"this.href=3D'javascript:';return =
true;">nicolas...@gmail.com</a> wrote:
<br>> I'd like to propose a new kind of destructor that gets called =
after a local=20
<br>> object's last use, instead of at the end of its scope.
<br>> [...]
<br>
<br>General follow-up... I'm not sure I'm in favor of this proposal=
in
<br>general, but I don't see it as feasible to make it a type property.=
You
<br>are almost inevitably going to have cases where the feature needs to be
<br>controlled on a per-variable basis, and having to produce duplicate
<br>types (and convert between them!) is not practical, not to mention that
<br>you may want to use it on types outside your control. (You mention
<br>matrices a lot; well, what if I'm using Eigen matrices and want thi=
s?)
<br>
<br>And then it occurred to me... we have the `register` keyword just
<br>sitting there. And you keep referring to register allocation of
<br>scalars... it seems that the old meaning of `register` is almost exactl=
y
<br>what you want.
<br>
<br>It may also make sense to make it UB to take and retain a reference to
<br>any `register` variable, including references to members of the same. I=
f
<br>we *really* wanted to be safe, we could make `register` a qualifier
<br>(i.e. allow its use on function parameters) and make it *ill-formed* to
<br>take a (non-`register`) reference to a `register` variable.</blockquote=
><div><br>So now you want `const virtual register` qualifiers on variables?=
Do we <i>really</i> need that?<br><br>The attribute approach seems so much=
cleaner.</div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/3e6d3a32-714f-4de5-8f2a-fdba73286e9c%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/3e6d3a32-714f-4de5-8f2a-fdba73286e9c=
%40isocpp.org</a>.<br />
------=_Part_4298_1758960806.1472496777227--
------=_Part_4297_1477428899.1472496777227--
.
Author: Nicolas Capens <nicolas.capens@gmail.com>
Date: Mon, 29 Aug 2016 18:54:49 +0000
Raw View
--001a11471562a9eff7053b3a66d3
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Fri, Aug 26, 2016 at 10:39 PM Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
wrote:
> On Friday, August 26, 2016 at 12:21:42 PM UTC-7, Nicolas Capens wrote:
>
>> On Fri, Aug 26, 2016 at 1:16 PM, Ren Industries <renind...@gmail.com>
>> wrote:
>>
>>> Why is it such a terrible imposition to require manual interaction to
>>> enforce this behavior? I don't buy your argument that it is similar to
>>> register allocation; that's a QOI not a standards issue.
>>>
>>
>> Consider this simple statement:
>>
>> x =3D a * b * c;
>>
>> Assume they're all scalars, and a, b, and c are no longer used after thi=
s
>> statement. That means liveness analysis will make their registers availa=
ble
>> for other variables, without you having to worry about it. But if instea=
d
>> these variables were huge matrices and you had to manually free their
>> storage to minimize memory consumption, then it would look something lik=
e
>> this:
>>
>> Matrix t =3D a * b;
>> a.~Matrix();
>> b.~Matrix();
>> x =3D t * c;
>> t.~Matrix();
>> c.~Matrix();
>>
>
> Well, it would look like this:
>
> x =3D a * b * c;
> a.clear();
> b.clear();
> c.clear();
>
> Or, if you wanted to be more C++11'ish about it,
>
> x =3D std::move(a) * std::move(b) * std::move(c);
>
> to indicate that you're really done using those named variables. It's
> really not a big deal.
>
It is a big deal. That was just a trivial example, but it already makes
things significantly less elegant. Now imagine manually indicating the end
of the live range of every Reactor
<https://swiftshader.googlesource.com/SwiftShader/+/master/docs/Reactor.md>
variable in this code:
https://swiftshader.googlesource.com/SwiftShader/+/master/src/Shader/SetupR=
outine.cpp
Also
note that you'd have to update it for every change to the actual
algorithms, and you'd need perfect test coverage of every path. This is
also one of the shorter Reactor functions in that project.
I'd like to separate the algorithms that I'm trying to express, from the
optimizations that are performed on it. Currently those optimizations have
to be done at run-time. With eager destruction some of it would be done at
static compile time. And that's just one of the three use cases
<https://groups.google.com/a/isocpp.org/forum/#!msg/std-proposals/IUxA4cx8y=
Hc/yKNqKl8hDgAJ>
I envision for this. I'm sure there's more. So please don't discard this as
not a big deal. One way to understand its value even more is by imagining
we've had it for a long time and then it gets taken away. The closest thing
to that would be to not have liveness analysis for register allocation and
thus required manually indicating the end of the lifetime of each scalar
variable. That's clearly unacceptable. Yet that's what we're dealing with
today for objects. I think we can come up with a feature to improve on that=
..
> I hope the above example illustrates that this is very similar to registe=
r
>> allocation, and it's a standards issue that we don't get this behavior
>> today for non-scalar types.
>>
>
> You've already realized that we *do* get this behavior today for
> trivially destructible types, and in general we get this behavior for eve=
ry
> type *by the as-if rule* (for types whose destructors have no observable
> side effects). Your one remaining concern is that we currently don't get
> this behavior for destructors whose side effects are observable.
>
Correct.
> Here we *seem to* have two cases:
> (Case 1) Destructors whose side effects are "important", such as
> ~std::lock_guard<std::mutex>.
> (Case 2) Destructors whose side effects are "unimportant", such as
> ~std::string.
>
Exactly. Let's optimize case 2. Note though that we wouldn't want to do it
for std::string itself to avoid breaking legacy content. It can be used for
new classes which have clearly opted into the eager destruction behavior
and for which the correct usage is intuitive. I'm being intentionally vague
about what that means exactly. I just don't want there to be any confusion
that I'm not proposing to alter any legacy behavior.
> Let's consider what might happen if we allowed std::string's destructor t=
o
> run "eagerly." Some people in this thread have already shown one problem=
:
>
> std::string x =3D "hello";
> char *y =3D &x[0];
> use(x);
> // run x's destructor now?
> std::cout << y << std::endl;
>
> Here, we are done with the variable x, but we aren't done with the object
> referenced by x =E2=80=94 the object that would be destroyed.
>
Yes, this is a problem, but let's not get deterred by that. Note that it's
also possible to still have a reference to an object that got destructed at
the end of its scope. That's a problem too. It could have been partially
mitigated by not destroying objects until the end of the function. Some
languages go even farther by using garbage collection. So it's all just
part of a spectrum of lifetime management solutions. Each has its
advantages and disadvantages, and I'm just proposing a new one with its own
advantages but also some additional disadvantages.
So with that in mind, my suggestion is that it should be invalid to keep
using a reference to the internal storage after the last explicit use of
the object. Note that for this particular example all you have to do is use
x again, instead of y. For self-contained objects that would be the norm
anyway. A string class with fewer ways to access its contents would help
enforce that.
> But okay, let's postulate that std::string is a bad candidate for eager
> destruction because it allows the user to get a pointer into its innards.
> After all, std::string also unsafely allows us to do things like this =E2=
=80=94
>
> std::string x =3D "hello";
> char *y =3D &x[0];
> x =3D "world";
> std::cout << y << std::endl; // UB
>
> So let's promise not to do anything stupid with pointers, okay? *Now* are
> we foolproof?
> Well. The side-effect of ~std::string that is observable under the curren=
t
> rules is its memory deallocation, which results in some calls to operator
> delete[] and so on. What could go wrong if we allow that deallocation to
> happen eagerly, given that we've promised not to do anything stupid with
> pointers?
>
> std::string x =3D "hello";
> if (true) {
> std::lock_guard<std::mutex> lk(mtx);
> use(x);
> // run x's destructor now?
> }
>
> Here we are performing our last operation on x while holding a mutex lock=
..
> Our last operation ("use(x)") is presumably something cheap and fast, or
> else we would try to do it outside the lock. But the destructor call, by
> definition, frees memory, which means it's not cheap. (Allocating memory =
is
> slower yet, but deallocating memory isn't always super cheap either.) And
> in fact it probably tries to take a global lock itself, under some
> circumstances, so now we're holding our original lock on "mtx" through a
> very slow and possibly even *blocking* memory-deallocation operation.
> Well, *that's* not good!
>
This is another carefully constructed example of a problem for which an
equivalent problem exists with destruction at end of scope (by moving x's
definition into the conditional block). Granted, it's more obvious that way
that the object will get destructed while the lock is held, but I doubt a
lot of people would even be conscious about it before it shows up in a
profiler. And when you're really serious about performance you're going to
make sure that eager destruction is helping you instead of slowing things
down. It's kind of in the name itself. Eager or lazy strategies are not
inherently better one versus the other. It depends on the situation.
Likewise lazy destruction can be the cause of many performance issues.
I'll put this down as another example why eager destruction should be used
with care. But it doesn't convince me at all that it wouldn't be a valuable
feature.
> Okay, so we shouldn't use eager destruction for types that expose
> references to their internals; and we shouldn't use eager destruction for
> types whose destructors might block on synchronization or I/O (because
> those types might get eagerly destructed under a mutex); and it goes
> without saying that we shouldn't use eager destruction for types whose
> destructors might *throw*; and we shouldn't use eager destruction for
> types whose destructors are trivial (because we get eager destruction for
> free under the as-if rule in those cases).
>
> So what cases have we got left at this point where eager destruction is
> *possible*? Certainly your motivating use-case of "Matrix" isn't a
> candidate, both because of the internal-reference problem and because of
> the memory-deallocation-is-a-blocking-operation problem. My above (Case =
1)
> and (Case 2) turn out to have collapsed into a single case:
> (Case 1) Destructors whose side effects *might be important to somebody.*
>
I think you're dismissing it too easily because of the blocking operation
problem. That's really just a rare situation. By a similar argument we
could dismiss lazy destruction as not viable. That's clearly not very
sensible. Again, it's all just part of a spectrum of lifetime management
solutions and we have to value each for their advantages and cope with
their disadvantages.
So I'd rather focus our effort on determining whether eager destructions
should be done aggressively or conservatively. The most aggressive option
is to call the destructor after the last local use of the object's name. It
has the nice property of being fully deterministic and easy to understand
by humans, but also has a considerable risk of not being used correctly and
causing issues. Slightly less aggressive is to also require the compiler to
track local references as an alias for the object. It doesn't have many
practical uses but eliminates at least one case that would cause issues, at
virtually no cost. More conservative solutions would allow/require the
compiler to track non-local references as well, but would require dropping
determinism guarantees or imposing demands on static analysis.
I don't have strong arguments yet for or against these different options.
> my $.02,
> =E2=80=93Arthur
>
--=20
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 e=
mail 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/CAE7XuEW62F63pNt1Gihu_W6FU1gEOtLg0_8QUYhA%3DnEjd=
GWv9Q%40mail.gmail.com.
--001a11471562a9eff7053b3a66d3
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Fri=
, Aug 26, 2016 at 10:39 PM Arthur O'Dwyer <<a href=3D"mailto:arthur.=
j.odwyer@gmail.com">arthur.j.odwyer@gmail.com</a>> wrote:<br></div><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #cc=
c solid;padding-left:1ex"><div dir=3D"ltr">On Friday, August 26, 2016 at 12=
:21:42 PM UTC-7, Nicolas Capens wrote:</div><div dir=3D"ltr"><blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #cc=
c solid;padding-left:1ex"><div dir=3D"ltr"><div><div class=3D"gmail_quote">=
On Fri, Aug 26, 2016 at 1:16 PM, Ren Industries <span dir=3D"ltr"><<a re=
l=3D"nofollow">renind...@gmail.com</a>></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"><div dir=3D"ltr">Why is it such a terrib=
le imposition to require manual interaction to enforce this behavior? I don=
't buy your argument that it is similar to register allocation; that=
9;s a QOI not a standards issue.</div></blockquote><div><br></div><div>Cons=
ider this simple statement:</div><div><br></div><div>=C2=A0 =C2=A0 x =3D a =
* b * c;</div><div><br></div><div>Assume they're all scalars, and a, b,=
and c are no longer used after this statement. That means liveness analysi=
s will make their registers available for other variables, without you havi=
ng to worry about it. But if instead these variables were huge matrices and=
you had to manually free their storage to minimize memory consumption, the=
n it would look something like this:</div><div><br></div><div>=C2=A0 =C2=A0=
Matrix t =3D a * b;</div><div>=C2=A0 =C2=A0 a.~Matrix();</div><div>=C2=A0 =
=C2=A0 b.~Matrix();</div><div>=C2=A0 =C2=A0 x =3D t * c;</div><div>=C2=A0 =
=C2=A0 t.~Matrix();</div><div>=C2=A0 =C2=A0 c.~Matrix();</div></div></div><=
/div></blockquote><div><br></div></div><div dir=3D"ltr"><div>Well, it would=
look like this:</div></div><div dir=3D"ltr"><div><br></div><div>=C2=A0 =C2=
=A0 x =3D a * b * c;</div></div><div dir=3D"ltr"><div>=C2=A0 =C2=A0 a.clear=
();</div><div>=C2=A0 =C2=A0 b.clear();</div><div>=C2=A0 =C2=A0 c.clear();</=
div><div><br></div><div>Or, if you wanted to be more C++11'ish about it=
,</div><div><br></div><div>=C2=A0 =C2=A0 x =3D std::move(a) * std::move(b) =
* std::move(c);</div><div><br></div><div>to indicate that you're really=
done using those named variables. It's really not a big deal.</div></d=
iv></blockquote><div><br></div><div>It is a big deal. That was just a trivi=
al example, but it already makes things significantly less elegant. Now ima=
gine manually indicating the end of the live range of every <a href=3D"http=
s://swiftshader.googlesource.com/SwiftShader/+/master/docs/Reactor.md">Reac=
tor</a> variable in this code:=C2=A0<a href=3D"https://swiftshader.googleso=
urce.com/SwiftShader/+/master/src/Shader/SetupRoutine.cpp">https://swiftsha=
der.googlesource.com/SwiftShader/+/master/src/Shader/SetupRoutine.cpp</a>=
=C2=A0Also note that you'd have to update it for every change to the ac=
tual algorithms, and you'd need perfect test coverage of every path. Th=
is is also one of the shorter Reactor functions in that project.</div><div>=
<br></div><div>I'd like to separate the algorithms that I'm trying =
to express, from the optimizations that are performed on it. Currently thos=
e optimizations have to be done at run-time. With eager destruction some of=
it would be done at static compile time. And that's just one of the <a=
href=3D"https://groups.google.com/a/isocpp.org/forum/#!msg/std-proposals/I=
UxA4cx8yHc/yKNqKl8hDgAJ">three use cases</a> I envision for this. I'm s=
ure there's more. So please don't discard this as not a big deal. O=
ne way to understand its value even more is by imagining we've had it f=
or a long time and then it gets taken away. The closest thing to that would=
be to not have liveness analysis for register allocation and thus required=
manually indicating the end of the lifetime of each scalar variable. That&=
#39;s clearly unacceptable. Yet that's what we're dealing with toda=
y for objects. I think we can come up with a feature to improve on that.</d=
iv><div>=C2=A0</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"><blockq=
uote 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>I hope the above example illustrates that this is very similar to re=
gister allocation, and it's a standards issue that we don't get thi=
s behavior today for non-scalar types.<br></div></div></div></blockquote><d=
iv><br></div></div><div dir=3D"ltr"><div>You've already realized that w=
e <i>do</i> get this behavior today for trivially destructible types, and i=
n general we get this behavior for every type <i>by the as-if rule</i> (for=
types whose destructors have no observable side effects).=C2=A0 Your one r=
emaining concern is that we currently don't get this behavior for destr=
uctors whose side effects are observable.</div></div></blockquote><div><br>=
</div><div>Correct.</div><div>=C2=A0</div><blockquote class=3D"gmail_quote"=
style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv dir=3D"ltr"><div>Here we <i><b>seem to</b></i> have two cases:</div><div=
>(Case 1) Destructors whose side effects are "important", such as=
~std::lock_guard<std::mutex>.</div><div>(Case 2) Destructors whose s=
ide effects are "unimportant", such as ~std::string.</div></div><=
/blockquote><div><br></div><div>Exactly. Let's optimize case 2. Note th=
ough that we wouldn't want to do it for std::string itself to avoid bre=
aking legacy content. It can be used for new classes which have clearly opt=
ed into the eager destruction behavior and for which the correct usage is i=
ntuitive. I'm being intentionally vague about what that means exactly. =
I just don't want there to be any confusion that I'm not proposing =
to alter any legacy behavior.</div><div>=C2=A0</div><blockquote class=3D"gm=
ail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-le=
ft:1ex"><div dir=3D"ltr"><div>Let's consider what might happen if we al=
lowed std::string's destructor to run "eagerly." =C2=A0Some p=
eople in this thread have already shown one problem:</div><div><br></div><d=
iv>=C2=A0 =C2=A0 std::string x =3D "hello";</div><div>=C2=A0 =C2=
=A0 char *y =3D &x[0];</div><div>=C2=A0 =C2=A0 use(x);</div><div>=C2=A0=
=C2=A0 // run x's destructor now?</div><div><div>=C2=A0 =C2=A0 std::co=
ut << y << std::endl;</div></div><div><br></div><div>Here, we a=
re done with the variable x, but we aren't done with the object referen=
ced by x =E2=80=94 the object that would be destroyed.</div></div></blockqu=
ote><div><br></div><div>Yes, this is a problem, but let's not get deter=
red by that. Note that it's also possible to still have a reference to =
an object that got destructed at the end of its scope. That's a problem=
too. It could have been partially mitigated by not destroying objects unti=
l the end of the function. Some languages go even farther by using garbage =
collection. So it's all just part of a spectrum of lifetime management =
solutions. Each has its advantages and disadvantages, and I'm just prop=
osing a new one with its own advantages but also some additional disadvanta=
ges.</div><div><br></div><div>So with that in mind, my suggestion is that i=
t should be invalid to keep using a reference to the internal storage after=
the last explicit use of the object. Note that for this particular example=
all you have to do is use <font face=3D"monospace">x</font> again, instead=
of <font face=3D"monospace">y</font>. For self-contained objects that woul=
d be the norm anyway. A string class with fewer ways to access its contents=
would help enforce that.</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>But okay, let's postulate that std::string is=
a bad candidate for eager destruction because it allows the user to get a =
pointer into its innards. After all, std::string also unsafely allows us to=
do things like this =E2=80=94</div><div><br></div><div><div>=C2=A0 =C2=A0 =
std::string x =3D "hello";</div><div>=C2=A0 =C2=A0 char *y =3D &a=
mp;x[0];</div></div><div>=C2=A0 =C2=A0 x =3D "world";</div><div>=
=C2=A0 =C2=A0 std::cout << y << std::endl; =C2=A0// UB</div><di=
v><br></div><div>So let's promise not to do anything stupid with pointe=
rs, okay? <i>Now</i> are we foolproof?</div><div>Well. The side-effect of ~=
std::string that is observable under the current rules is its memory deallo=
cation, which results in some calls to operator delete[] and so on. What co=
uld go wrong if we allow that deallocation to happen eagerly, given that we=
've promised not to do anything stupid with pointers?</div><div><br></d=
iv><div>=C2=A0 =C2=A0 std::string x =3D "hello";</div><div>=C2=A0=
=C2=A0 if (true) {</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 std::lock_guard&l=
t;std::mutex> lk(mtx);</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 use(x);</di=
v><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 // run x's destructor now?</div><div=
></div><div>=C2=A0 =C2=A0 }<br></div><div><br></div><div>Here we are perfor=
ming our last operation on x while holding a mutex lock. Our last operation=
("use(x)") is presumably something cheap and fast, or else we wo=
uld try to do it outside the lock. But the destructor call, by definition, =
frees memory, which means it's not cheap. (Allocating memory is slower =
yet, but deallocating memory isn't always super cheap either.) And in f=
act it probably tries to take a global lock itself, under some circumstance=
s, so now we're holding our original lock on "mtx" through a =
very slow and possibly even <i>blocking</i> memory-deallocation operation. =
Well, <i>that's</i> not good!</div></div></blockquote><div><br></div><d=
iv>This is another carefully constructed example of a problem for which an =
equivalent problem exists with destruction at end of scope (by moving <font=
face=3D"monospace">x</font>'s definition into the conditional block). =
Granted, it's more obvious that way that the object will get destructed=
while the lock is held, but I doubt a lot of people would even be consciou=
s about it before it shows up in a profiler. And when you're really ser=
ious about performance you're going to make sure that eager destruction=
is helping you instead of slowing things down. It's kind of in the nam=
e itself. Eager or lazy strategies are not inherently better one versus the=
other. It depends on the situation. Likewise lazy destruction can be the c=
ause of many performance issues.</div><div><br></div><div>I'll put this=
down as another example why eager destruction should be used with care. Bu=
t it doesn't convince me at all that it wouldn't be a valuable feat=
ure.</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margi=
n:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">=
<div>Okay, so we shouldn't use eager destruction for types that expose =
references to their internals; and we shouldn't use eager destruction f=
or types whose destructors might block on synchronization or I/O (because t=
hose types might get eagerly destructed under a mutex); and it goes without=
saying that we shouldn't use eager destruction for types whose destruc=
tors might <i>throw</i>; and we shouldn't use eager destruction for typ=
es whose destructors are trivial (because we get eager destruction for free=
under the as-if rule in those cases).</div><div><br></div><div>So what cas=
es have we got left at this point where eager destruction is <i>possible</i=
>? Certainly your motivating use-case of "Matrix" isn't a can=
didate, both because of the internal-reference problem and because of the m=
emory-deallocation-is-a-blocking-operation problem.=C2=A0 My above (Case 1)=
and (Case 2) turn out to have collapsed into a single case:</div><div>(Cas=
e 1) Destructors whose side effects <i>might be important to somebody.</i><=
/div></div></blockquote><div><br></div><div>I think you're dismissing i=
t too easily because of the blocking operation problem. That's really j=
ust a rare situation. By a similar argument we could dismiss lazy destructi=
on as not viable. That's clearly not very sensible. Again, it's all=
just part of a spectrum of lifetime management solutions and we have to va=
lue each for their advantages and cope with their disadvantages.</div><div>=
<br></div><div>So I'd rather focus our effort on determining whether ea=
ger destructions should be done aggressively or conservatively. The most ag=
gressive option is to call the destructor after the last local use of the o=
bject's name. It has the nice property of being fully deterministic and=
easy to understand by humans, but also has a considerable risk of not bein=
g used correctly and causing issues. Slightly less aggressive is to also re=
quire the compiler to track local references as an alias for the object. It=
doesn't have many practical uses but eliminates at least one case that=
would cause issues, at virtually no cost. More conservative solutions woul=
d allow/require the compiler to track non-local references as well, but wou=
ld require dropping determinism guarantees or imposing demands on static an=
alysis.</div><div><br></div><div>I don't have strong arguments yet for =
or against these different options.</div><div>=C2=A0</div><blockquote class=
=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr"><div>my $.02,</div><div>=E2=80=93Arthur</div=
></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" 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/CAE7XuEW62F63pNt1Gihu_W6FU1gEOtLg0_8Q=
UYhA%3DnEjdGWv9Q%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAE7XuEW62F63pN=
t1Gihu_W6FU1gEOtLg0_8QUYhA%3DnEjdGWv9Q%40mail.gmail.com</a>.<br />
--001a11471562a9eff7053b3a66d3--
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Mon, 29 Aug 2016 15:05:56 -0400
Raw View
On 2016-08-29 14:46, Nicol Bolas wrote:
> 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
I think having explicit temporary types might help here:
std::string::c_str() -> char const* register; // declaration
// error: taking reference of register-qualified type.
const auto &str = std::string(...).c_str();
Obviously, it is too late to change std::string this way, but it would
help us write better API's going forward. Specifically:
> 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.
....it would be a way to solve this.
On 2016-08-29 14:52, Nicol Bolas wrote:
> So now you want `const virtual register` qualifiers on variables? Do we
> *really* need that?
Well... *yes*. For exactly the reason given above. Making it a qualifier
makes it possible to actually *solve* some of these problems, at least
by making them explicitly ill-formed rather than just subtly broken.
Mind, this idea isn't fully baked, but it might (*might*) have potential...
--
Matthew
--
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/57C48794.6020105%40gmail.com.
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Mon, 29 Aug 2016 15:27:17 -0400
Raw View
On 2016-08-29 15:05, Matthew Woehlke wrote:
> On 2016-08-29 14:46, Nicol Bolas wrote:
>> 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
>
> I think having explicit temporary types might help here:
>
> std::string::c_str() -> char const* register; // declaration
>
> // error: taking reference of register-qualified type.
> const auto &str = std::string(...).c_str();
>
> Obviously, it is too late to change std::string this way, but it would
> help us write better API's going forward. Specifically:
>
>> 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.
>
> ...it would be a way to solve this.
To expand on that: a `register` qualified return type is an explicit
temporary which *may not* be lifetime extended. For example:
foo(char const* register sp);
bar(char const*);
std::string s{"abcd"};
// s::c_str() -> char const* register
// s::operator[](size_t) -> char& register
// okay; return value of c_str is "destroyed" after the call to foo()
foo(s.c_str());
// okay; return value of operator[] is "destroyed" after assignment
s[0] = 'x';
// error: would lifetime-extend a `register` type
auto p = s.c_str();
auto& c = s[0];
// error: no matching function
bar(s.c_str());
A `register` qualified function parameter may not be stored in non-local
storage. (Basically, a parameter that is register qualified is a promise
- an *enforced* promise - that the callee will not retain a reference to
that parameter or any of its innards.)
There problems to be worked out, and some may be insurmountable. It's a
very preliminary idea, more in the 'is this interesting enough to be
worth pursuing?' stage. (In particular, non-pointer/reference-types need
to be copyable to non-register-qualified types, and *possibly* to
const-qualified references.)
The biggest problem, though, is that using the qualifier would be
extremely pervasive, i.e. you have to use it end to end in your entire
API or you run into all sorts of problems. For example, copying a
register-qualified type would need a copy ctor that takes a
register-qualified parameter...
--
Matthew
--
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/57C48C95.8040202%40gmail.com.
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 29 Aug 2016 13:38:08 -0700 (PDT)
Raw View
------=_Part_543_1234584666.1472503088435
Content-Type: multipart/alternative;
boundary="----=_Part_544_1114345054.1472503088436"
------=_Part_544_1114345054.1472503088436
Content-Type: text/plain; charset=UTF-8
On Monday, August 29, 2016 at 3:05:59 PM UTC-4, Matthew Woehlke wrote:
>
> On 2016-08-29 14:46, Nicol Bolas wrote:
> > 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
>
> I think having explicit temporary types might help here:
>
> std::string::c_str() -> char const* register; // declaration
>
> // error: taking reference of register-qualified type.
> const auto &str = std::string(...).c_str();
>
> Obviously, it is too late to change std::string this way, but it would
> help us write better API's going forward.
How would that solve the problem? How does the compiler connect the return
value's lifetime to the lifetime of one of the function parameters?* Which*
parameter should it connect it to? All of them?
And why would you use `register` of all things for that?
> Specifically:
>
> > 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.
>
> ...it would be a way to solve this.
>
> On 2016-08-29 14:52, Nicol Bolas wrote:
> > So now you want `const virtual register` qualifiers on variables? Do we
> > *really* need that?
>
> Well... *yes*. For exactly the reason given above. Making it a qualifier
> makes it possible to actually *solve* some of these problems, at least
> by making them explicitly ill-formed rather than just subtly broken.
>
P0066 provided a more comprehensive solution to lifetime analysis. And it
was ultimately rejected
<https://botondballo.wordpress.com/2015/11/09/trip-report-c-standards-meeting-in-kona-october-2015/>
..
--
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/a90060ce-0316-4c11-b123-9326cf91b16d%40isocpp.org.
------=_Part_544_1114345054.1472503088436
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Monday, August 29, 2016 at 3:05:59 PM UTC-4, Matthew Wo=
ehlke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2016-08-29 14:4=
6, Nicol Bolas wrote:
<br>> This problem is fundamentally identical to the temporary lifetime =
extension=20
<br>> problem. Namely, that this works:
<br>>=20
<br>> const auto &str =3D std::string(...);
<br>> //use str
<br>>=20
<br>> While this does not:
<br>>=20
<br>> const auto &str =3D std::string(...).c_str();
<br>> //use str
<br>
<br>I think having explicit temporary types might help here:
<br>
<br>=C2=A0 std::string::c_str() -> char const* register; // declaration
<br>
<br>=C2=A0 // error: taking reference of register-qualified type.
<br>=C2=A0 const auto &str =3D std::string(...).c_str();
<br>
<br>Obviously, it is too late to change std::string this way, but it would
<br>help us write better API's going forward.</blockquote><div><br>How =
would that solve the problem? How does the compiler connect the return valu=
e's lifetime to the lifetime of one of the function parameters?<i> Whic=
h</i> parameter should it connect it to? All of them?<br><br>And why would =
you use `register` of all things for that?<br>=C2=A0</div><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;">Specifically:
<br>
<br>> The compiler does not and *cannot* know, in all cases, whether a=
=20
<br>> return value of a function contains a pointer/reference to an=20
<br>> argument or an element of an argument.
<br>
<br>...it would be a way to solve this.
<br>
<br>On 2016-08-29 14:52, Nicol Bolas wrote:
<br>> So now you want `const virtual register` qualifiers on variables? =
Do we=20
<br>> *really* need that?
<br>
<br>Well... *yes*. For exactly the reason given above. Making it a qualifie=
r
<br>makes it possible to actually *solve* some of these problems, at least
<br>by making them explicitly ill-formed rather than just subtly broken.<br=
></blockquote><div><br>P0066 provided a more comprehensive solution to life=
time analysis. And it was <a href=3D"https://botondballo.wordpress.com/2015=
/11/09/trip-report-c-standards-meeting-in-kona-october-2015/">ultimately re=
jected</a>.</div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/a90060ce-0316-4c11-b123-9326cf91b16d%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/a90060ce-0316-4c11-b123-9326cf91b16d=
%40isocpp.org</a>.<br />
------=_Part_544_1114345054.1472503088436--
------=_Part_543_1234584666.1472503088435--
.
Author: Nicolas Capens <nicolas.capens@gmail.com>
Date: Mon, 29 Aug 2016 21:21:12 +0000
Raw View
--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 <<a href=3D"mailto:jmckesson@gmail.com">j=
mckesson@gmail.com</a>> 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's clear to me now that I haven't =
defined "last use" 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'm trying to solve. The first example is one where I'd like t=
he 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 vari=
able:</div></div></blockquote></div><div dir=3D"ltr"><div><br>I don'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 "eager" 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'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'=
;t (necessarily) know what's going on in `forward_as_tuple`. All the co=
mpiler sees is that you're passing a reference in, and you're getti=
ng at tuple<T&> out. How could the compiler know that `tpl` conta=
ins a reference to `t`? It can't; not without doing <i>serious</i> usag=
e analysis.<br><br>And that'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'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'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'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're stuck while technically we'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't be member variables or global variables. The above c=
ode would then simply not compile and you'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'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`'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=
"scalar types". But what you'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's not made in the type's decla=
ration (you can get references to `int`, after all). It'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=
9;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 destr=
uction happen, that too should be a property of the type.</div><div><br></d=
iv><div>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.</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'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'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"><some_syntax></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'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 "leg=
itimate" 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 "last use" 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't our biggest point of contention righ=
t now, but we'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" 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--
.
Author: Peter Koch Larsen <peter.koch.larsen@gmail.com>
Date: Tue, 30 Aug 2016 00:07:11 +0200
Raw View
On Mon, Aug 29, 2016 at 8:54 PM, Nicolas Capens
<nicolas.capens@gmail.com> wrote:
>
>
> On Fri, Aug 26, 2016 at 10:39 PM Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
> wrote:
>>
>> On Friday, August 26, 2016 at 12:21:42 PM UTC-7, Nicolas Capens wrote:
>>>
>>> On Fri, Aug 26, 2016 at 1:16 PM, Ren Industries <renind...@gmail.com>
>>> wrote:
>>>>
>>>> Why is it such a terrible imposition to require manual interaction to
>>>> enforce this behavior? I don't buy your argument that it is similar to
>>>> register allocation; that's a QOI not a standards issue.
>>>
>>>
>>> Consider this simple statement:
>>>
>>> x = a * b * c;
>>>
>>> Assume they're all scalars, and a, b, and c are no longer used after this
>>> statement. That means liveness analysis will make their registers available
>>> for other variables, without you having to worry about it. But if instead
>>> these variables were huge matrices and you had to manually free their
>>> storage to minimize memory consumption, then it would look something like
>>> this:
>>>
>>> Matrix t = a * b;
>>> a.~Matrix();
>>> b.~Matrix();
>>> x = t * c;
>>> t.~Matrix();
>>> c.~Matrix();
>>
>>
>> Well, it would look like this:
>>
>> x = a * b * c;
>> a.clear();
>> b.clear();
>> c.clear();
>>
>> Or, if you wanted to be more C++11'ish about it,
>>
>> x = std::move(a) * std::move(b) * std::move(c);
>>
>> to indicate that you're really done using those named variables. It's
>> really not a big deal.
>
>
> It is a big deal. That was just a trivial example, but it already makes
> things significantly less elegant. Now imagine manually indicating the end
> of the live range of every Reactor variable in this code:
> https://swiftshader.googlesource.com/SwiftShader/+/master/src/Shader/SetupRoutine.cpp
> Also note that you'd have to update it for every change to the actual
> algorithms, and you'd need perfect test coverage of every path. This is also
> one of the shorter Reactor functions in that project.
I just had a glance at the code in your link. A ~200 line function
seemingly in dire need of refactoring.
Such code is not a good example to argue about liveness of variables.
You should refactor the code
into smaller, logical elements and demonstrate that "eager
destruction" is still needed.
/Peter
--
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/CANPtknx5mC09L9x%2B2WmCagWL476DwUGqrthN%3D1pe4tizLj0v7w%40mail.gmail.com.
.
Author: Nicolas Capens <nicolas.capens@gmail.com>
Date: Tue, 30 Aug 2016 03:06:57 +0000
Raw View
--001a1147b01ca51808053b4146e0
Content-Type: text/plain; charset=UTF-8
On Sat, Aug 27, 2016 at 4:54 PM Nicol Bolas <jmckesson@gmail.com> 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. 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. 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.
--
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/CAE7XuEWSecp0fS%2B6m84rF6%2B9cBcy5yXJL3SOPbUqEXGj9YfffQ%40mail.gmail.com.
--001a1147b01ca51808053b4146e0
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 4:54 PM Nicol Bolas <<a href=3D"mailto:jmckesson@gmail.com" ta=
rget=3D"_blank">jmckesson@gmail.com</a>> wrote:<br></div><blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;pa=
dding-left:1ex"><div dir=3D"ltr">The other advantage to making eager destru=
ction a function of how the object is declared is that it can be used with =
<i>anything</i>. We couldn't declare that any currently existing standa=
rd 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 o=
bjects don't violate the "never get pointers/references" rule=
..<br><br>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 wh=
atever 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 th=
ey follow the rules).</div></blockquote><div><br></div><div>That's inde=
ed 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 s=
torage. Also, if eager destructions isn't fully deterministic but imple=
mentation dependent, then something that might work fine on one compiler ca=
n cause issues on another. This is somewhat less likely when a class was de=
signed with eager destruction in mind in the first place.</div><div><br></d=
iv><div>Anyway, I'm not against providing the user with more options. P=
erhaps we can simply allow to specify eager destruction both at the class l=
evel and per declaration.</div><div></div></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/CAE7XuEWSecp0fS%2B6m84rF6%2B9cBcy5yXJ=
L3SOPbUqEXGj9YfffQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAE7XuEWSecp0=
fS%2B6m84rF6%2B9cBcy5yXJL3SOPbUqEXGj9YfffQ%40mail.gmail.com</a>.<br />
--001a1147b01ca51808053b4146e0--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 29 Aug 2016 21:55:35 -0700 (PDT)
Raw View
------=_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 <<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-ma=
ilto=3D"DNlBEMXyEQAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'java=
script:';return true;" onclick=3D"this.href=3D'javascript:';ret=
urn true;">jmck...@gmail.com</a>> 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't declare that any currently existing standard libr=
ary types use eager destruction. And yet, there's no reason why we coul=
dn't use it with most such types, so long as the uses of those objects =
don't violate the "never get pointers/references" rule.<br><b=
r>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 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's indeed an a=
ttractive argument. I'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"><<</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'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's destructor has not been called after the last use of that=
variable's name in the control flow of that variable's scope.<br><=
br>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 <i>nothing</i>. It allows compilers to provide qui=
ck destruction in simple cases, but it doesn't force them into doing cr=
azy analysis of conditional logic. They can if they want, but that'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=
'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'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.<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 "eager" 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't need=
the burden of those responsibilities, so they don'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'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'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" 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--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 29 Aug 2016 22:17:52 -0700 (PDT)
Raw View
------=_Part_2044_1063203769.1472534272456
Content-Type: multipart/alternative;
boundary="----=_Part_2045_1968658985.1472534272457"
------=_Part_2045_1968658985.1472534272457
Content-Type: text/plain; charset=UTF-8
On Monday, August 29, 2016 at 5:21:28 PM UTC-4, Nicolas Capens wrote:
>
> On Sat, Aug 27, 2016 at 11:10 AM Nicol Bolas <jmck...@gmail.com
> <javascript:>> wrote:
>
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.
>
You wouldn't necessarily get such an error. Why? Because `std::tuple`
doesn't *have* to store the object as a true member variable. It can be
implemented by creating an internal buffer big enough to hold all of the
objects, then use placement new to initialize them. And thus, it is a
de-facto member without being a member subobject.
Also, the tuple above stores a reference, not a value. Which also defies
static analysis, because the tuple may not be storing it as a true member
subobject. Are you going to forbid using placement new as well?
One more thing. Let's pretend that forbidding the use of these types as
subobjects, globals, or placement `new` would solve the problem. Why is
this a good thing? I don't know of a class type where it is reasonable to
forbid objects of that type from being a member subobject of another class.
When you're having to add unpleasant features to types just to make your
idea functional, that is generally a sign that it's not the right feature.
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.
>
It would be an attribute on the automatic variable declaration, not of a
type specifier.
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.
>
Why would I want or *need* to? Precisely how much performance improvement
would eager destruction get me in terms of building Reactor functions? Why
is eager destruction of paramount optimization concern with Reactor usage?
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.
>
As proven elsewhere, you cannot avoid the pitfalls of such types through
interface alone. At *best*, you make it slightly less fragile. But all of
the template cases still fail, since they won't necessarily care about your
interface.
Also such code would be hard to refactor.
>
Why? How does this attribute change refactoring at all?
Using this attribute is an optimization tool. Optimization happens *after*
refactoring. If you're about to refactor some code, you would generally rip
out all of these attributes first.
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.
>
.... huh? I'm talking about flow control analysis; the nature of the type is
completely irrelevant. If you can determine what "the earliest possible"
point is with `Streamer`, then you can determine it with `Matrix` too.
> 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/42620c68-a931-4492-895e-5811d51a0dbb%40isocpp.org.
------=_Part_2045_1968658985.1472534272457
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Monday, August 29, 2016 at 5:21:28 PM UTC-4, Nicolas Ca=
pens 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"><d=
iv><div dir=3D"ltr">On Sat, Aug 27, 2016 at 11:10 AM Nicol Bolas <<a hre=
f=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"UJV1GOjfEQAJ" =
rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:';return tr=
ue;" onclick=3D"this.href=3D'javascript:';return true;">jmck...@gma=
il.com</a>> wrote:<br></div></div></div></blockquote><div></div><blockqu=
ote 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_q=
uote"><div></div><div>By the way, one other potential way this could be sol=
ved is to not allow storing referenced to classes with eager destruction.</=
div></div></div></blockquote><blockquote class=3D"gmail_quote" style=3D"mar=
gin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><=
div dir=3D"ltr"><div class=3D"gmail_quote"><div> That is, they can be funct=
ion 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 erro=
r message about it.</div></div></div></blockquote><div><br>You wouldn't=
necessarily get such an error. Why? Because `std::tuple` doesn't <i>ha=
ve</i> to store the object as a true member variable. It can be implemented=
by creating an internal buffer big enough to hold all of the objects, then=
use placement new to initialize them. And thus, it is a de-facto member wi=
thout being a member subobject.<br><br>Also, the tuple above stores a refer=
ence, not a value. Which also defies static analysis, because the tuple may=
not be storing it as a true member subobject. Are you going to forbid usin=
g placement new as well?<br><br>One more thing. Let's pretend that forb=
idding the use of these types as subobjects, globals, or placement `new` wo=
uld solve the problem. Why is this a good thing? I don't know of a clas=
s type where it is reasonable to forbid objects of that type from being a m=
ember subobject of another class.<br><br>When you're having to add unpl=
easant features to types just to make your idea functional, that is general=
ly a sign that it's not the right feature.<br><br></div><blockquote cla=
ss=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"><=
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>The problem, as Matt ha=
s said, is that your feature works at the <i>type</i> level. To make this f=
eature work, it has to happen at the <i>usage</i> level. The person declari=
ng that variable <i>must explicitly state</i> that they will use the type a=
s a pure value. That they won't get pointers/references to itself or it=
s contents.<br><br>The right way to handle this is to make it a function of=
the object's declaration:<br><br><div style=3D"background-color:rgb(25=
0,250,250);border-color:rgb(187,187,187);border-style:solid;border-width:1p=
x;word-wrap:break-word"><code><div><span style=3D"color:#008"><some_synt=
ax></span><span style=3D"color:#000"> TypeName varName;</span></div></co=
de></div></div></div></blockquote><div><br></div><div>If this can be part o=
f a typedef (like <font face=3D"monospace">const</font>), then that seems r=
easonable to me.</div></div></div></blockquote><div><br>It would be an attr=
ibute on the automatic variable declaration, not of a type specifier.<br><b=
r></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0=
..8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div =
class=3D"gmail_quote"><div>Note that I really wouldn't want to annotate=
the use of a <a href=3D"https://swiftshader.googlesource.com/SwiftShader/+=
/HEAD/docs/Reactor.md" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"th=
is.href=3D'https://swiftshader.googlesource.com/SwiftShader/+/HEAD/docs=
/Reactor.md';return true;" onclick=3D"this.href=3D'https://swiftsha=
der.googlesource.com/SwiftShader/+/HEAD/docs/Reactor.md';return true;">=
Reactor</a> type at each variable declaration.</div></div></div></blockquot=
e><div><br>Why would I want or <i>need</i> to? Precisely how much performan=
ce improvement would eager destruction get me in terms of building Reactor =
functions? Why is eager destruction of paramount optimization concern with =
Reactor usage?<br><br></div><blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><d=
iv dir=3D"ltr"><div class=3D"gmail_quote"><div></div><div>I just think it w=
ould end up being used as part of a typedef, all the time. For "legiti=
mate" 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 i=
t correctly would be much more painful than using a class which always uses=
eager destruction and helps you avoid the pitfalls by design.</div></div><=
/div></blockquote><div><br>As proven elsewhere, you cannot avoid the pitfal=
ls of such types through interface alone. At <i>best</i>, you make it sligh=
tly less fragile. But all of the template cases still fail, since they won&=
#39;t necessarily care about your interface.<br><br></div><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;"><div dir=3D"ltr"><div class=3D"gmail_quote"><di=
v>Also such code would be hard to refactor.</div></div></div></blockquote><=
div><br>Why? How does this attribute change refactoring at all?<br><br>Usin=
g this attribute is an optimization tool. Optimization happens <i>after</i>=
refactoring. If you're about to refactor some code, you would generall=
y rip out all of these attributes first.<br><br></div><blockquote class=3D"=
gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc so=
lid;padding-left: 1ex;"><div dir=3D"ltr"><div class=3D"gmail_quote"><div>It=
seems mentally less demanding to me to just know that for certain types yo=
u always have to avoid certain scenarios.</div></div></div></blockquote><bl=
ockquote 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"gm=
ail_quote"><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 na=
med use.<br><br>This allows template programming to actually work. If a tem=
plate function needed to use eager destruction, then the template would exp=
ress that in the declaration of an automatic variable. And therefore, the p=
erson writing that template function would know that they cannot do tricks =
on the variable like `forward_as_tuple`.<br><br>Also, there still need to b=
e clarifications on what "last use" means. Consider:<br><br><div =
style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);bo=
rder-style:solid;border-width:1px;word-wrap:break-word"><code><div><span st=
yle=3D"color:#606">Matrix</span><span style=3D"color:#000"> a </span><span =
style=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#660">...</span><span style=3D"color:#000"><br></span><span sty=
le=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"color:#000"><br></span><span style=3D"color:#660">{</span><span style=
=3D"color:#000"><br>=C2=A0 </span><span style=3D"color:#606">Matrix</span><=
span style=3D"color:#000"> b </span><span style=3D"color:#660">=3D</span><s=
pan style=3D"color:#000"> a </span><span style=3D"color:#660">*</span><span=
style=3D"color:#000"> whatever</span><span style=3D"color:#660">;</span><s=
pan style=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 style=3D"color:#660">}</span><span style=3D"color:#000"><br></span></d=
iv></code></div><br>When does `a` get destroyed? I guess it would have to b=
e after the loop, right? Otherwise, the compiler would have to advance the =
loop prematurely to see if `a` needs to be destroyed.<br><br>How does this =
work with conditional branching? Or God help you, with `goto`?</div></div><=
/blockquote><div><br></div><div>Good points. For the Streamer use case it w=
ould make sense to be aggressive about calling the destructor at the earlie=
st possible, while for the Matrix case it might be reasonable to wait until=
the next branch merge point.</div></div></div></blockquote><div><br>... hu=
h? I'm talking about flow control analysis; the nature of the type is c=
ompletely irrelevant. If you can determine what "the earliest possible=
" point is with `Streamer`, then you can determine it with `Matrix` to=
o.<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"=
ltr"><div class=3D"gmail_quote"><div>This isn't our biggest point of co=
ntention right now, but we'll need to get back to this. Thanks for brin=
ging it up.</div></div></div>
</blockquote></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/42620c68-a931-4492-895e-5811d51a0dbb%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/42620c68-a931-4492-895e-5811d51a0dbb=
%40isocpp.org</a>.<br />
------=_Part_2045_1968658985.1472534272457--
------=_Part_2044_1063203769.1472534272456--
.
Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Tue, 30 Aug 2016 02:49:58 -0700 (PDT)
Raw View
------=_Part_261_754441559.1472550598404
Content-Type: multipart/alternative;
boundary="----=_Part_262_1837149260.1472550598404"
------=_Part_262_1837149260.1472550598404
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
W dniu czwartek, 25 sierpnia 2016 23:24:39 UTC+2 u=C5=BCytkownik Nicolas Ca=
pens=20
napisa=C5=82:
>
> Thanks all for the initial feedback! It's clear to me now that I haven't=
=20
> defined "last use" very well, and giving it an accurate definition based =
on=20
> 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=
=20
> to solve. The first example is one where I'd like the heap memory managed=
=20
> by an object to get freed at the same point where a scalar variable's=20
> 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) =3D ...;
> Matrix b(10'000, 10'000) =3D ...;
> Matrix c(10'000, 10'000) =3D ...;
>
> a +=3D b; // Last use of b, destruct before the next line
> a +=3D c;
> }
>
> The alternative of using explicit destruction is really inconvenient:
>
> {
> Matrix a(10'000, 10'000) =3D ...;
> Matrix b(10'000, 10'000) =3D ...;
> Matrix c(10'000, 10'000) =3D ...;
>
> a +=3D b;
> b.~Matrix();
> a +=3D c;
> }
>
> As is reducing the scope:
>
> {
> Matrix a(10'000, 10'000) =3D ...;
>
> {
> Matrix b(10'000, 10'000) =3D ...;
> a +=3D b;
> }
>
> Matrix c(10'000, 10'000) =3D ...; =20
> a +=3D c;
> }
>
>
Note that to some extent you can fix this problem with std::optional (in=20
C++17, now in a TS):
=20
{
Matrix a(10'000, 10'000) =3D ...;
optional<Matrix> b(in_place, 10'000, 10'000) =3D ...;
Matrix c(10'000, 10'000) =3D ...;
a +=3D *b;
b =3D nullopt;
a +=3D c;
}
Regards,
&rzej;
--=20
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 e=
mail 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/ce82b6f6-524e-4520-a3f3-aa3b1aa35940%40isocpp.or=
g.
------=_Part_262_1837149260.1472550598404
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>W dniu czwartek, 25 sierpnia 2016 23:24:39 UTC+2 u=
=C5=BCytkownik Nicolas Capens napisa=C5=82:<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'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 comp=
iler lingo is going to be tricky.<div><br></div><div>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:</div><div><br></div><div><font fa=
ce=3D"monospace">=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 public:</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"monospace">=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 doub=
le *m;</font></div><div><font face=3D"monospace">=C2=A0 =C2=A0 };</font></d=
iv><div><font face=3D"monospace"><br></font></div><div><font face=3D"monosp=
ace">=C2=A0 =C2=A0 {</font></div><div><font face=3D"monospace">=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 Matrix a(10'000, 10'000) =3D ...;</font></div><di=
v><font face=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 Matrix b(10'000,=
10'000) =3D ...;<br></font></div><div><font face=3D"monospace">=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 Matrix c(10'000, 10'000) =3D ...;<br></font></=
div><div><font face=3D"monospace"><br></font></div><div><font face=3D"monos=
pace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 a=C2=A0+=3D b; =C2=A0 // Last use of b, d=
estruct before 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"mono=
space">=C2=A0 =C2=A0 =C2=A0}</font></div><div><br></div><div dir=3D"ltr"><d=
iv>The alternative of using explicit destruction is really inconvenient:</d=
iv><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=
'000, 10'000) =3D ...;</font></div><div><font face=3D"monospace">=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 Matrix b(10'000, 10'000) =3D ...;<br></=
font></div><div><font face=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 Matrix=
c(10'000, 10'000) =3D ...;<br></font></div><div><font face=3D"mono=
space"><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"monospace">=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"m=
onospace">=C2=A0 =C2=A0 }</font></div></div><div><br></div><div>As is reduc=
ing the scope:</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'000, 10'000) =3D ...;</font></div><div><font fa=
ce=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'000, 10'000) =3D ...;</fon=
t></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'000, 10'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 }</fo=
nt></div></div><div><div><br></div></div></div></div></blockquote><div><br>=
Note that to some extent you can fix this problem with std::optional (in C+=
+17, now in a TS):<br><br>=C2=A0<div class=3D"prettyprint" style=3D"backgro=
und-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-sty=
le: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"pretty=
print"><div class=3D"subprettyprint"><span style=3D"color: #660;" class=3D"=
styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br>=C2=A0 </span><span style=3D"color: #606;" class=3D"styled-b=
y-prettify">Matrix</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> a</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
(</span><span style=3D"color: #066;" class=3D"styled-by-prettify">10</span>=
<span style=3D"color: #080;" class=3D"styled-by-prettify">'000, 10'=
</span><span style=3D"color: #066;" class=3D"styled-by-prettify">000</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">...;</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br>=C2=A0 optional</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify"><</span><span style=3D"color: #606;" class=3D=
"styled-by-prettify">Matrix</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">></span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> b</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">in_pla=
ce</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #066;" class=3D"styled-by-prettify">10</span><span style=3D"co=
lor: #080;" class=3D"styled-by-prettify">'000, 10'</span><span styl=
e=3D"color: #066;" class=3D"styled-by-prettify">000</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">...;</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br>=C2=A0 </span><span style=3D"color: #606;" class=3D"styled-by-prettif=
y">Matrix</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
c</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><=
span style=3D"color: #066;" class=3D"styled-by-prettify">10</span><span sty=
le=3D"color: #080;" class=3D"styled-by-prettify">'000, 10'</span><s=
pan style=3D"color: #066;" class=3D"styled-by-prettify">000</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">...;</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br><br>=C2=A0 a </span><span style=3D"color: #660;" class=3D"styl=
ed-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">b</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 b </span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> nullopt</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br>=C2=A0 a </span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">+=3D</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> c</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">}</span></div></code></div><div><font face=3D"monospace"><br>Re=
gards,<br>&rzej;<br></font></div></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/ce82b6f6-524e-4520-a3f3-aa3b1aa35940%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/ce82b6f6-524e-4520-a3f3-aa3b1aa35940=
%40isocpp.org</a>.<br />
------=_Part_262_1837149260.1472550598404--
------=_Part_261_754441559.1472550598404--
.
Author: edward.catmur@mavensecurities.com
Date: Tue, 30 Aug 2016 03:51:48 -0700 (PDT)
Raw View
------=_Part_4999_2014121254.1472554308235
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Tuesday, 30 August 2016 10:49:58 UTC+1, Andrzej Krzemie=C5=84ski wrote:
>
>
>
> W dniu czwartek, 25 sierpnia 2016 23:24:39 UTC+2 u=C5=BCytkownik Nicolas =
Capens=20
> napisa=C5=82:
>>
>> Thanks all for the initial feedback! It's clear to me now that I haven't=
=20
>> defined "last use" very well, and giving it an accurate definition based=
on=20
>> 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 tryin=
g=20
>> to solve. The first example is one where I'd like the heap memory manage=
d=20
>> by an object to get freed at the same point where a scalar variable's=20
>> 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) =3D ...;
>> Matrix b(10'000, 10'000) =3D ...;
>> Matrix c(10'000, 10'000) =3D ...;
>>
>> a +=3D b; // Last use of b, destruct before the next line
>> a +=3D c;
>> }
>>
>> The alternative of using explicit destruction is really inconvenient:
>>
>> {
>> Matrix a(10'000, 10'000) =3D ...;
>> Matrix b(10'000, 10'000) =3D ...;
>> Matrix c(10'000, 10'000) =3D ...;
>>
>> a +=3D b;
>> b.~Matrix();
>> a +=3D c;
>> }
>>
>> As is reducing the scope:
>>
>> {
>> Matrix a(10'000, 10'000) =3D ...;
>>
>> {
>> Matrix b(10'000, 10'000) =3D ...;
>> a +=3D b;
>> }
>>
>> Matrix c(10'000, 10'000) =3D ...; =20
>> a +=3D c;
>> }
>>
>>
> Note that to some extent you can fix this problem with std::optional (in=
=20
> C++17, now in a TS):
>
> =20
> {
> Matrix a(10'000, 10'000) =3D ...;
> optional<Matrix> b(in_place, 10'000, 10'000) =3D ...;
> Matrix c(10'000, 10'000) =3D ...;
>
> a +=3D *b;
> b =3D nullopt;
> a +=3D c;
> }
>
>
You can do better than that using the exchange-empty idiom:
a +=3D *std::exchange(b, nullopt);
However I believe that OP considers this also too clumsy (look for=20
discussion of std::move above).
One thing I haven't seen mentioned yet in this discussion is that=20
allocation and deallocation is already elidable per [expr.new]/10. This=20
means that e.g. the destructor of std::string is not an observable=20
operation.
--=20
This e-mail together with any attachments (the "Message") is confidential=
=20
and may contain privileged information. If you are not the intended=20
recipient or if you have received this e-mail in error, please notify the=
=20
sender immediately and permanently delete this Message from your system.=20
Do not copy, disclose or distribute the information contained in this=20
Message.
=20
Maven Investment Partners Ltd (No. 07511928), Maven Derivatives Ltd (No.=20
07511840) , MVN Asset Management Limited (No. 09659116), Maven Europe Ltd=
=20
(No. 08966593) & Maven Securities Holding Ltd (No. 07505438) are registered=
=20
as companies in England and Wales and their registered address is Level 3,=
=20
6 Bevis Marks, London EC3A 7BA, United Kingdom. The companies=E2=80=99 VAT =
No. is=20
135539016. Only Maven Derivatives Ltd and MVN Asset Management Limited are=
=20
authorised by the Financial Conduct Authority (Maven Derivatives Ltd FRN:=
=20
607267, MVN Asset Management Limited FRN: 714429)
--=20
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 e=
mail 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/999474d0-dc7e-4431-acbb-968af6588342%40isocpp.or=
g.
------=_Part_4999_2014121254.1472554308235
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, 30 August 2016 10:49:58 UTC+1, Andrzej Krzemie=
=C5=84ski wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr"><br><br>W dniu czwartek, 25 sierpnia 2016 23:24:39 UTC+2 u=C5=BCytkowni=
k Nicolas Capens napisa=C5=82:<blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div =
dir=3D"ltr">Thanks all for the initial feedback! It's clear to me now t=
hat I haven't defined "last use" very well, and giving it an =
accurate definition based on my limited knowledge of compiler lingo is goin=
g to be tricky.<div><br></div><div>So let me take a step back and describe =
what real-world issues I'm trying to solve. The first example is one wh=
ere I'd like the heap memory managed by an object to get freed at the s=
ame point where a scalar variable's register would be made available fo=
r a different variable:</div><div><br></div><div><font face=3D"monospace">=
=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 public:</=
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"monospace">=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 auto ~Matrix(); =C2=A0 // Eager destructor</fon=
t></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><di=
v><font face=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 double *m;</font></d=
iv><div><font face=3D"monospace">=C2=A0 =C2=A0 };</font></div><div><font fa=
ce=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'000, 10'000) =3D ...;</font></div><div><font face=3D"m=
onospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 Matrix b(10'000, 10'000) =3D =
....;<br></font></div><div><font face=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 Matrix c(10'000, 10'000) =3D ...;<br></font></div><div><font fa=
ce=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 before t=
he 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 dir=3D"ltr"><div>The alternativ=
e of using explicit destruction is really inconvenient:</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'000, 10'=
000) =3D ...;</font></div><div><font face=3D"monospace">=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 Matrix b(10'000, 10'000) =3D ...;<br></font></div><div><=
font face=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 Matrix c(10'000, 10=
'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"monospace">=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"monospace">=C2=A0 =C2=A0 {</f=
ont></div><div><font face=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 Matrix =
a(10'000, 10'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'000, 10'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'000, 10'000) =3D ...;=C2=A0=C2=A0<br></font></di=
v><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><br></div></div></div></div></blockquote><div><br>Note that to s=
ome extent you can fix this problem with std::optional (in C++17, now in a =
TS):<br><br>=C2=A0<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:#660">{</span><span style=3D"color:#000=
"><br>=C2=A0 </span><span style=3D"color:#606">Matrix</span><span style=3D"=
color:#000"> a</span><span style=3D"color:#660">(</span><span style=3D"colo=
r:#066">10</span><span style=3D"color:#080">'000, 10'</span><span s=
tyle=3D"color:#066">000</span><span style=3D"color:#660">)</span><span styl=
e=3D"color:#000"> </span><span style=3D"color:#660">=3D</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">...;</span><span style=
=3D"color:#000"><br>=C2=A0 optional</span><span style=3D"color:#660"><</=
span><span style=3D"color:#606">Matrix</span><span style=3D"color:#660">>=
;</span><span style=3D"color:#000"> b</span><span style=3D"color:#660">(</s=
pan><span style=3D"color:#000">in_place</span><span style=3D"color:#660">,<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#066">10</spa=
n><span style=3D"color:#080">'000, 10'</span><span style=3D"color:#=
066">000</span><span style=3D"color:#660">)</span><span style=3D"color:#000=
"> </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> =
</span><span style=3D"color:#660">...;</span><span style=3D"color:#000"><br=
>=C2=A0 </span><span style=3D"color:#606">Matrix</span><span style=3D"color=
:#000"> c</span><span style=3D"color:#660">(</span><span style=3D"color:#06=
6">10</span><span style=3D"color:#080">'000, 10'</span><span style=
=3D"color:#066">000</span><span style=3D"color:#660">)</span><span style=3D=
"color:#000"> </span><span style=3D"color:#660">=3D</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#660">...;</span><span style=3D"colo=
r:#000"><br><br>=C2=A0 a </span><span style=3D"color:#660">+=3D</span><span=
style=3D"color:#000"> </span><span style=3D"color:#660">*</span><span styl=
e=3D"color:#000">b</span><span style=3D"color:#660">;</span><span style=3D"=
color:#000"><br>=C2=A0 b </span><span style=3D"color:#660">=3D</span><span =
style=3D"color:#000"> nullopt</span><span style=3D"color:#660">;</span><spa=
n style=3D"color:#000"><br>=C2=A0 a </span><span style=3D"color:#660">+=3D<=
/span><span style=3D"color:#000"> c</span><span style=3D"color:#660">;</spa=
n><span style=3D"color:#000"><br></span><span style=3D"color:#660">}</span>=
</div></code></div><div><br></div></div></div></blockquote><div><br></div><=
div>You can do better than that using the exchange-empty idiom:</div><div><=
br></div><div class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187=
, 187); word-wrap: break-word; background-color: rgb(250, 250, 250);"><code=
class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: =
#000;" class=3D"styled-by-prettify">a </span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">+=3D</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">*</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">:=
:</span><span style=3D"color: #000;" class=3D"styled-by-prettify">exchange<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">b</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> nullopt</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br></span></div></code></div><div><br></div><d=
iv>However I believe that OP considers this also too clumsy (look for discu=
ssion of std::move above).</div><div><br></div><div>One thing I haven't=
seen mentioned yet in this discussion is that allocation and deallocation =
is already elidable per [expr.new]/10. This means that e.g. the destructor =
of std::string is not an observable operation.</div></div>
<br>
<p><font color=3D"#222222" face=3D"Arial, sans-serif"><span style=3D"font-s=
ize:13px">This e-mail together with any attachments (the "Message"=
;) is confidential and may contain privileged information. If you are not t=
he intended recipient or if you have received this e-mail in error, please =
notify the sender immediately and permanently delete this Message from your=
system. =C2=A0Do not copy, disclose or distribute the information containe=
d in this Message.</span></font></p><p><font color=3D"#222222" face=3D"Aria=
l, sans-serif"><span style=3D"font-size:13px">=C2=A0</span></font></p><p><f=
ont color=3D"#222222" face=3D"Arial, sans-serif"><span style=3D"font-size:1=
3px">Maven Investment Partners Ltd (No. 07511928), Maven Derivatives Ltd (N=
o. 07511840) , MVN Asset Management Limited (No. 09659116), Maven Europe Lt=
d (No. 08966593) & Maven Securities Holding Ltd (No. 07505438) are regi=
stered as companies in England and Wales and their registered address is Le=
vel 3, 6 Bevis Marks, London EC3A 7BA, United Kingdom. The companies=E2=80=
=99 VAT No. is 135539016. Only Maven Derivatives Ltd and MVN Asset Manageme=
nt Limited are authorised by the Financial Conduct Authority (Maven Derivat=
ives Ltd FRN: 607267, MVN Asset Management Limited FRN: 714429)</span></fon=
t></p>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/999474d0-dc7e-4431-acbb-968af6588342%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/999474d0-dc7e-4431-acbb-968af6588342=
%40isocpp.org</a>.<br />
------=_Part_4999_2014121254.1472554308235--
.
Author: Edward Catmur <ed@catmur.co.uk>
Date: Tue, 30 Aug 2016 04:07:40 -0700 (PDT)
Raw View
------=_Part_337_73619561.1472555260123
Content-Type: multipart/alternative;
boundary="----=_Part_338_1043379957.1472555260124"
------=_Part_338_1043379957.1472555260124
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Tuesday, 30 August 2016 10:49:58 UTC+1, Andrzej Krzemie=C5=84ski wrote:
>
>
>
> W dniu czwartek, 25 sierpnia 2016 23:24:39 UTC+2 u=C5=BCytkownik Nicolas =
Capens=20
> napisa=C5=82:
>>
>> Thanks all for the initial feedback! It's clear to me now that I haven't=
=20
>> defined "last use" very well, and giving it an accurate definition based=
on=20
>> 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 tryin=
g=20
>> to solve. The first example is one where I'd like the heap memory manage=
d=20
>> by an object to get freed at the same point where a scalar variable's=20
>> 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) =3D ...;
>> Matrix b(10'000, 10'000) =3D ...;
>> Matrix c(10'000, 10'000) =3D ...;
>>
>> a +=3D b; // Last use of b, destruct before the next line
>> a +=3D c;
>> }
>>
>> The alternative of using explicit destruction is really inconvenient:
>>
>> {
>> Matrix a(10'000, 10'000) =3D ...;
>> Matrix b(10'000, 10'000) =3D ...;
>> Matrix c(10'000, 10'000) =3D ...;
>>
>> a +=3D b;
>> b.~Matrix();
>> a +=3D c;
>> }
>>
>> As is reducing the scope:
>>
>> {
>> Matrix a(10'000, 10'000) =3D ...;
>>
>> {
>> Matrix b(10'000, 10'000) =3D ...;
>> a +=3D b;
>> }
>>
>> Matrix c(10'000, 10'000) =3D ...; =20
>> a +=3D c;
>> }
>>
>>
> Note that to some extent you can fix this problem with std::optional (in=
=20
> C++17, now in a TS):
>
> =20
> {
> Matrix a(10'000, 10'000) =3D ...;
> optional<Matrix> b(in_place, 10'000, 10'000) =3D ...;
> Matrix c(10'000, 10'000) =3D ...;
>
> a +=3D *b;
> b =3D nullopt;
> a +=3D c;
> }
>
(Reposting from correct account; sorry for the noise.)
You can do better than that using the exchange-empty idiom:
=20
a +=3D *std::exchange(b, nullopt);
However I believe that OP considers this also too clumsy (look for=20
discussion of std::move above).
=20
One thing I haven't seen mentioned yet in this discussion is that=20
allocation and deallocation is already elidable per [expr.new]/10. This=20
means that e.g. the destructor of std::string is not an observable=20
operation.
--=20
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 e=
mail 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/7857a4a6-29af-47c0-b6ab-c555a0005935%40isocpp.or=
g.
------=_Part_338_1043379957.1472555260124
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, 30 August 2016 10:49:58 UTC+1, Andrzej Krzemie=
=C5=84ski wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr"><br><br>W dniu czwartek, 25 sierpnia 2016 23:24:39 UTC+2 u=C5=BCytkowni=
k Nicolas Capens napisa=C5=82:<blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div =
dir=3D"ltr">Thanks all for the initial feedback! It's clear to me now t=
hat I haven't defined "last use" very well, and giving it an =
accurate definition based on my limited knowledge of compiler lingo is goin=
g to be tricky.<div><br></div><div>So let me take a step back and describe =
what real-world issues I'm trying to solve. The first example is one wh=
ere I'd like the heap memory managed by an object to get freed at the s=
ame point where a scalar variable's register would be made available fo=
r a different variable:</div><div><br></div><div><font face=3D"monospace">=
=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 public:</=
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"monospace">=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 auto ~Matrix(); =C2=A0 // Eager destructor</fon=
t></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><di=
v><font face=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 double *m;</font></d=
iv><div><font face=3D"monospace">=C2=A0 =C2=A0 };</font></div><div><font fa=
ce=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'000, 10'000) =3D ...;</font></div><div><font face=3D"m=
onospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 Matrix b(10'000, 10'000) =3D =
....;<br></font></div><div><font face=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 Matrix c(10'000, 10'000) =3D ...;<br></font></div><div><font fa=
ce=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 before t=
he 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 dir=3D"ltr"><div>The alternativ=
e of using explicit destruction is really inconvenient:</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'000, 10'=
000) =3D ...;</font></div><div><font face=3D"monospace">=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 Matrix b(10'000, 10'000) =3D ...;<br></font></div><div><=
font face=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 Matrix c(10'000, 10=
'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"monospace">=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"monospace">=C2=A0 =C2=A0 {</f=
ont></div><div><font face=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 Matrix =
a(10'000, 10'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'000, 10'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'000, 10'000) =3D ...;=C2=A0=C2=A0<br></font></di=
v><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><br></div></div></div></div></blockquote><div><br>Note that to s=
ome extent you can fix this problem with std::optional (in C++17, now in a =
TS):<br><br>=C2=A0<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:#660">{</span><span style=3D"color:#000=
"><br>=C2=A0 </span><span style=3D"color:#606">Matrix</span><span style=3D"=
color:#000"> a</span><span style=3D"color:#660">(</span><span style=3D"colo=
r:#066">10</span><span style=3D"color:#080">'000, 10'</span><span s=
tyle=3D"color:#066">000</span><span style=3D"color:#660">)</span><span styl=
e=3D"color:#000"> </span><span style=3D"color:#660">=3D</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">...;</span><span style=
=3D"color:#000"><br>=C2=A0 optional</span><span style=3D"color:#660"><</=
span><span style=3D"color:#606">Matrix</span><span style=3D"color:#660">>=
;</span><span style=3D"color:#000"> b</span><span style=3D"color:#660">(</s=
pan><span style=3D"color:#000">in_place</span><span style=3D"color:#660">,<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#066">10</spa=
n><span style=3D"color:#080">'000, 10'</span><span style=3D"color:#=
066">000</span><span style=3D"color:#660">)</span><span style=3D"color:#000=
"> </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> =
</span><span style=3D"color:#660">...;</span><span style=3D"color:#000"><br=
>=C2=A0 </span><span style=3D"color:#606">Matrix</span><span style=3D"color=
:#000"> c</span><span style=3D"color:#660">(</span><span style=3D"color:#06=
6">10</span><span style=3D"color:#080">'000, 10'</span><span style=
=3D"color:#066">000</span><span style=3D"color:#660">)</span><span style=3D=
"color:#000"> </span><span style=3D"color:#660">=3D</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#660">...;</span><span style=3D"colo=
r:#000"><br><br>=C2=A0 a </span><span style=3D"color:#660">+=3D</span><span=
style=3D"color:#000"> </span><span style=3D"color:#660">*</span><span styl=
e=3D"color:#000">b</span><span style=3D"color:#660">;</span><span style=3D"=
color:#000"><br>=C2=A0 b </span><span style=3D"color:#660">=3D</span><span =
style=3D"color:#000"> nullopt</span><span style=3D"color:#660">;</span><spa=
n style=3D"color:#000"><br>=C2=A0 a </span><span style=3D"color:#660">+=3D<=
/span><span style=3D"color:#000"> c</span><span style=3D"color:#660">;</spa=
n><span style=3D"color:#000"><br></span><span style=3D"color:#660">}</span>=
</div></code></div></div></div></blockquote><div><br></div><div><p class=3D=
"MsoNormal">(Reposting from correct account; sorry for the noise.)</p><p cl=
ass=3D"MsoNormal"><br></p><p class=3D"MsoNormal">You can do better than tha=
t using the exchange-empty idiom:<o:p></o:p></p>
<p class=3D"MsoNormal"><o:p>=C2=A0</o:p></p>
<p class=3D"MsoNormal" style=3D"background:#FAFAFA"></p><div class=3D"prett=
yprint" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-wor=
d; background-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div =
class=3D"subprettyprint"><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">a </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
+=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">*</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">std</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify">exchange</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">b</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> nullopt</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">);</span></div></code></div><p></p><p class=3D"MsoNormal"><br></p>
<p class=3D"MsoNormal">However I believe that OP considers this also too cl=
umsy
(look for discussion of std::move above).<o:p></o:p></p>
<p class=3D"MsoNormal"><o:p>=C2=A0</o:p></p>
<p class=3D"MsoNormal">One thing I haven't seen mentioned yet in this d=
iscussion is
that allocation and deallocation is already elidable per [expr.new]/10. Thi=
s
means that e.g. the destructor of std::string is not an observable operatio=
n.<o:p></o:p></p></div><div><br></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/7857a4a6-29af-47c0-b6ab-c555a0005935%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/7857a4a6-29af-47c0-b6ab-c555a0005935=
%40isocpp.org</a>.<br />
------=_Part_338_1043379957.1472555260124--
------=_Part_337_73619561.1472555260123--
.
Author: FrankHB1989 <frankhb1989@gmail.com>
Date: Tue, 30 Aug 2016 05:38:03 -0700 (PDT)
Raw View
------=_Part_45_723738256.1472560683257
Content-Type: multipart/alternative;
boundary="----=_Part_46_1492685317.1472560683257"
------=_Part_46_1492685317.1472560683257
Content-Type: text/plain; charset=UTF-8
It seems that some kind of strong liveness analysis (as so-called static
garbage collection) is need here, to infer the lifetime during translation.
Since it can be deterministic, it may be interestingly suitable for C++.
However, I don't like the idea of multiple "destructors"; too messy, e.g.
so called "destructor"/finalizer/IDisposable in some current languages.
And besides the "destructor" issue, I doubt the problem is over-simplified
too aggressively. Do you really want to create some kind of affine type
systems rather than extends the current one? (BTW, I don't like the
proposed syntactic notations. There may be just better a new keyword unless
you can wrapped the features in a library form.)
--
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/eef1301a-a5ca-4ff8-ba64-0f7ade794fd0%40isocpp.org.
------=_Part_46_1492685317.1472560683257
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">It seems that some kind of strong liveness analysis (as so=
-called static garbage collection) is need here, to infer the lifetime duri=
ng translation. Since it can be deterministic, it may be interestingly suit=
able for C++. However, I don't like the idea of multiple "destruct=
ors"; too messy, e.g. so called "destructor"/finalizer/IDisp=
osable in some current languages.<br><br>And besides the "destructor&q=
uot; issue, I doubt the problem is over-simplified too aggressively. Do you=
really want to create some kind of affine type systems rather than extends=
the current one? (BTW, I don't like the proposed syntactic notations. =
There may be just better a new keyword unless you can wrapped the features =
in a library form.)<br></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/eef1301a-a5ca-4ff8-ba64-0f7ade794fd0%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/eef1301a-a5ca-4ff8-ba64-0f7ade794fd0=
%40isocpp.org</a>.<br />
------=_Part_46_1492685317.1472560683257--
------=_Part_45_723738256.1472560683257--
.
Author: Nicolas Capens <nicolas.capens@gmail.com>
Date: Tue, 30 Aug 2016 14:12:07 +0000
Raw View
--001a1141136e7eeafa053b4a914d
Content-Type: text/plain; charset=UTF-8
On Mon, Aug 29, 2016 at 1:34 PM Ren Industries <renindustries@gmail.com>
wrote:
> I 100% disagree that manual freeing is not acceptable; as Arthur
> indicated, it is not particularly hard to work around.
> I agree with him; it is not a big deal.
>
There are also several people who seem to agree with me that eager
destruction is a feature worth exploring. Either way, while your opinion
has been duly noted despite any lack of clear counterarguments, if you
don't have anything constructive to add then I question why you're even
participating in the discussion. It's totally fine if you don't see any
future for this feature. It's just futile to try to convince people
otherwise who do, no matter how much "percent" you disagree.
> Furthermore, it's absolutely absurd you'd say "too bad" to working and
> quite important projects that do in fact use C++; that is not
> "implementation side"; it is a perfectly valid backend that does not in any
> way do "register allocation".
>
> We can picture machines that do not use registers; why exactly should we
> add an implementation detail to C++, which is defined in terms of an
> abstract machine NOT a real one?
>
First of all please note that my "too bad" was both conditional and not
intentional. I was just conveying an unfortunate fact about some new
language features. So don't shoot the messenger.
Secondly, C++ has "register" as a keyword. Sure, it's a deprecated one, but
it would be disingenuous to deny its history. Cross-compilation wasn't a
design consideration back then, and I doubt it's still anything more than
an afterthought. That doesn't mean I don't have sympathy for it. I happen
to have experience in GLSL to HLSL graphics shader translation, which is
crucial to all major web browsers on Windows. It's really annoying when the
target language doesn't have a direct equivalent of each feature. But I
can't blame spec authors from wanting to move ahead with additional
features.
Likewise Emscripten downright doesn't support certain features or supports
them poorly. It's unreasonable to expect the C++ standard to hold back on
adding any more features that would be hard or impossible to support.
I do not doubt the practical use for such a feature; in fact, I could use
> such a feature quite often, and manually annotate my code to make such
> features possible, even going so far as to occasionally use wrappers to
> make it easier. Just because I can see a feature is useful does not mean it
> deserves to be part of the standard, or that we should disrupt currently
> working code to implement it, especially when a library solution is so
> obvious.
>
It's always going to be a matter of opinion whether the gains outweigh the
costs. But first of all we need to maximize the gains and minimize the
costs. We're still in the relatively early phases of that exploitative
work, with currently some new ideas being passed around that could make it
a lot more attractive than what you might have initially envisioned.
Secondly, C++ has never really been a language that shies away from
features that may only have select use cases or are not foolproof. So even
if you don't think it "deserves" it, it might still be embraced by the
standard.
I'm a curious about your "obvious" library solution though, although I fear
it would just be another undesirable manual method.
> I understand what you mean by register allocation, but I again do not find
> it to be in any way similar beyond superficially, and once again, register
> allocation is part of implementation not the standard. It is completely
> possible for a compiler to do no register allocation at all; the reason it
> can is because of the "as if" rule. You want non-trivial destructors to be
> called out of order? Not allowed by the "as if" rule, for very good
> reasons. Trying to hack it in using implementation details is a bad idea.
>
Repeating that register allocation is part of the implementation is not
going to deter me in any way. It's one of the options for supporting eager
destruction. And while register allocation is not a literal part of the
standard, I'm going to repeat once more that it's only due to the
standard's specification that compilers are enabled to do it. Similarly we
need a change of the standard to accommodate eager destruction of objects.
And that's true regardless of whether we decide to make it merely a hint
and dependent on the implementation, or more deterministic. It looks like
you have a preference toward the latter. Perhaps you'd like to elaborate on
that with some constructive arguments.
> Guess that's "too bad" for you, then.
>
I will gladly accept any outcome of this discussion.
>
> On Mon, Aug 29, 2016 at 1:02 PM, Nicolas Capens <nicolas.capens@gmail.com>
> wrote:
>
>> On Fri, Aug 26, 2016 at 5:46 PM Ren Industries <renindustries@gmail.com>
>> wrote:
>>
>>> That in no way demonstrates it is similar to register allocation, which
>>> is, again, a QOI issue.
>>>
>>
>> My apologies. The example omitted how the equivalent scalar code would
>> have its registers freed up for use by other variables after their last
>> use. I thought that would be sufficiently clear. Here's an illustration of
>> that: http://compilers.cs.ucla.edu/fernando/projects/puzzles/tutorial/.
>> The end of the live ranges corresponds to where I'd like the destructors of
>> objects to be called. Let me know if the similarities are still not obvious
>> to you and I'll create a more detailed side-by-side example if I find the
>> time.
>>
>> Anyway, yes, register allocation is a quality of implementation issue.
>> One that is enabled by the standard allowing for it because scalars having
>> no side-effects on destruction. I want to enable that same freedom of
>> optimization for objects that do have side-effects, by telling the compiler
>> that we don't care about these side-effects to happen at the end of the
>> variable's scope.
>>
>>
>>> It is not necessarily the case that a compiler need do that, and I can
>>> think of at least a few counter examples. For example, there are projects
>>> that output C++ to javascript or java, which have no notion of register
>>> allocation as you point to it. These "machines" are perfectly valid C++
>>> targets, yet have absolutely no notion of what you are talking about.
>>>
>>
>> I realize that. But I shouldn't have to care if a compiler strictly needs
>> to do that today or not. I'm talking about adding a new feature to the
>> language, and this may involve adding some new implementation requirements.
>> If that causes some cross-compilers to no longer be able to support this
>> new version of C++ without some non-trivial effort, too bad. It's certainly
>> not my aim to make implementer's lives difficult, but I also don't want to
>> cripple or abandon the feature because of it.
>>
>> Indeed, C++ supports a huge variety of applications. More than you know
>>> of, it seems.
>>>
>>
>> You're talking about Emscripten and alike. That's implementation side. I
>> was talking about applications written in C++. You seemed to see no
>> practical uses for this feature, presumably because you hadn't encountered
>> such an application before. Did my trivial example clarify that manual
>> freeing of the resources is not acceptable, or do you still disagree?
>>
>>
>>> On Fri, Aug 26, 2016 at 3:21 PM, Nicolas Capens <
>>> nicolas.capens@gmail.com> wrote:
>>>
>>>> On Fri, Aug 26, 2016 at 1:16 PM, Ren Industries <
>>>> renindustries@gmail.com> wrote:
>>>>
>>>>> Why is it such a terrible imposition to require manual interaction to
>>>>> enforce this behavior? I don't buy your argument that it is similar to
>>>>> register allocation; that's a QOI not a standards issue.
>>>>>
>>>>
>>>> Consider this simple statement:
>>>>
>>>> x = a * b * c;
>>>>
>>>> Assume they're all scalars, and a, b, and c are no longer used after
>>>> this statement. That means liveness analysis will make their registers
>>>> available for other variables, without you having to worry about it. But if
>>>> instead these variables were huge matrices and you had to manually free
>>>> their storage to minimize memory consumption, then it would look something
>>>> like this:
>>>>
>>>> Matrix t = a * b;
>>>> a.~Matrix();
>>>> b.~Matrix();
>>>> x = t * c;
>>>> t.~Matrix();
>>>> c.~Matrix();
>>>>
>>>> Or if you wanted to do it with scopes:
>>>>
>>>> {
>>>> Matrix t;
>>>> {
>>>> Matrix a = ...;
>>>> Matrix b = ...;
>>>> t = a * b;
>>>> }
>>>> Matrix c = ...;
>>>> x = t * c;
>>>> }
>>>>
>>>> To me the original statement looks a whole lot easier to read and
>>>> maintain than the two workarounds. And this is just a trivial example! It
>>>> would become insane to do it for any realistic data processing code.
>>>>
>>>> Also I think that calling something a "terrible imposition" or not is
>>>> highly subjective. Many recent C++ features solve issues that already had
>>>> workarounds which some considered acceptable but were unworkable for
>>>> others. So please avoid being prejudiced by your own experience and having
>>>> no direct use for this yourself. C++ supports a huge variety of
>>>> applications.
>>>>
>>>> I hope the above example illustrates that this is very similar to
>>>> register allocation, and it's a standards issue that we don't get this
>>>> behavior today for non-scalar types.
>>>>
>>>>
>>>>> On Fri, Aug 26, 2016 at 1:05 PM, Nicolas Capens <
>>>>> nicolas.capens@gmail.com> wrote:
>>>>>
>>>>>>
>>>>>>
>>>>>> On Wed, Aug 24, 2016 at 4:22 PM Nevin Liber <nevin@eviloverlord.com>
>>>>>> wrote:
>>>>>>
>>>>>>> On 24 August 2016 at 15:16, <nicolas.capens@gmail.com> wrote:
>>>>>>>
>>>>>>>> The code would become littered with braces if you want to limit the
>>>>>>>> scope of each object to its miminal range,
>>>>>>>>
>>>>>>>
>>>>>>> I don't understand why you would want to do that. Could you
>>>>>>> elaborate?
>>>>>>>
>>>>>>
>>>>>> Certainly. I wrote down three practical use cases here
>>>>>> <https://groups.google.com/a/isocpp.org/forum/#!msg/std-proposals/IUxA4cx8yHc/yKNqKl8hDgAJ>
>>>>>> .
>>>>>>
>>>>>>
>>>>>>> And if the objects are truly independent and have no observable
>>>>>>> effect, can't a compiler do that under the as-if rule?
>>>>>>>
>>>>>>
>>>>>> The problem is that the objects I'm using do have side-effects, so
>>>>>> the compiler won't attempt to shorten their lifespan. But in my use cases
>>>>>> the side effects are "self-contained", i.e. you could treat them as scalars
>>>>>> and destruct them right after their last use.
>>>>>>
>>>>>>
>>>>>>> Also, if you wish to have a lifetime shorter than a scope for an
>>>>>>> object of type T, you can just use std::optional<T>.
>>>>>>>
>>>>>>
>>>>>> How would that work, without requiring manual actions to destruct it?
>>>>>>
>>>>>>
>>>>>>> Fortunately we don't, because today's compilers do liveness analysis
>>>>>>>> to optimize register allocation.
>>>>>>>>
>>>>>>>
>>>>>>> One of the huge benefits to C++ is that destruction happens at well
>>>>>>> defined times. This would break that.
>>>>>>>
>>>>>>
>>>>>> Yes, in many cases it will be preferable to keep the well defined
>>>>>> behavior of implicitly calling the destructor at the end of the variable's
>>>>>> scope. The opt-in feature I'm proposing should be used sparingly and
>>>>>> cautiously. But when used by a well written framework it should be
>>>>>> foolproof for the users of the framework, and offer them significant
>>>>>> benefits.
>>>>>>
>>>>>>
>>>>>>> --
>>>>>>> Nevin ":-)" Liber <mailto:nevin@eviloverlord.com> +1-847-691-1404
>>>>>>>
>>>>>>> --
>>>>>>> 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-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/CAGg_6%2BM3M43y_8jTg4mXce1sz7UQ5kzSkOVqL3F_nYEe-ogzNA%40mail.gmail.com
>>>>>>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAGg_6%2BM3M43y_8jTg4mXce1sz7UQ5kzSkOVqL3F_nYEe-ogzNA%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/CAE7XuEVobd1QW2jJYW-hGTLTPgQxRJM-QkL9jNovOkhaaoXQEw%40mail.gmail.com
>>>>>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAE7XuEVobd1QW2jJYW-hGTLTPgQxRJM-QkL9jNovOkhaaoXQEw%40mail.gmail.com?utm_medium=email&utm_source=footer>
>>>>>> .
>>>>>>
>>>>>
>>>>> --
>>>>> 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-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/CAMD6iD_8zsoqfYdUsY%2BQe_QNvzFsH4c9uUjNYzw5BRFiLQRE%2BQ%40mail.gmail.com
>>>>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAMD6iD_8zsoqfYdUsY%2BQe_QNvzFsH4c9uUjNYzw5BRFiLQRE%2BQ%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/CAE7XuEW%2BcRoF_T59wS53M%3DQrB85GOGydUXWoBfcmauKJTc5tAA%40mail.gmail.com.
--001a1141136e7eeafa053b4a914d
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 Mon, Aug 29=
, 2016 at 1:34 PM Ren Industries <<a href=3D"mailto:renindustries@gmail.=
com" target=3D"_blank">renindustries@gmail.com</a>> wrote:<br></div><blo=
ckquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #c=
cc solid;padding-left:1ex"><div dir=3D"ltr">I 100% disagree that manual fre=
eing is not acceptable; as Arthur indicated, it is not particularly hard to=
work around.<div>I agree with him; it is not a big deal.</div></div></bloc=
kquote><div><br></div></div><div dir=3D"ltr"><div class=3D"gmail_quote"><di=
v>There are also several people who seem to agree with me that eager destru=
ction is a feature worth exploring. Either way, while your opinion has been=
duly noted despite any lack of clear counterarguments, if you don't ha=
ve anything constructive to add then I question why you're even partici=
pating in the discussion. It's totally fine if you don't see any fu=
ture for this feature. It's just futile to try to convince people other=
wise who do, no matter how much "percent" you disagree.</div></di=
v></div><div dir=3D"ltr"><div class=3D"gmail_quote"><div>=C2=A0</div><block=
quote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc=
solid;padding-left:1ex"><div dir=3D"ltr"><div>Furthermore, it's absolu=
tely absurd you'd say "too bad" to working and quite importan=
t projects that do in fact use C++; that is not "implementation side&q=
uot;; it is a perfectly valid backend that does not in any way do "reg=
ister allocation".=C2=A0</div><div><br></div><div>We can picture machi=
nes that do not use registers; why exactly should we add an implementation =
detail to C++, which is defined in terms of an abstract machine NOT a real =
one?</div></div></blockquote><div><br></div></div></div><div dir=3D"ltr"><d=
iv class=3D"gmail_quote"><div>First of all please note that my "too ba=
d" was both conditional and not intentional. I was just conveying an u=
nfortunate fact about some new language features. So don't shoot the me=
ssenger.</div><div><br></div><div>Secondly, C++ has "register" as=
a keyword. Sure, it's a deprecated one, but it would be disingenuous t=
o deny its history. Cross-compilation wasn't a design consideration bac=
k then, and I doubt it's still anything more than an afterthought. That=
doesn't mean I don't have sympathy for it. I happen to have experi=
ence in GLSL to HLSL graphics shader translation, which is crucial to all m=
ajor web browsers on Windows. It's really annoying when the target lang=
uage doesn't have a direct equivalent of each feature. But I can't =
blame spec authors from wanting to move ahead with additional features.</di=
v><div><br></div><div>Likewise Emscripten downright doesn't support cer=
tain features or supports them poorly. It's unreasonable to expect the =
C++ standard to hold back on adding any more features that would be hard or=
impossible to support.</div></div></div><div dir=3D"ltr"><div class=3D"gma=
il_quote"><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"><d=
iv>I do not doubt the practical use for such a feature; in fact, I could us=
e such a feature quite often, and manually annotate my code to make such fe=
atures possible, even going so far as to occasionally use wrappers to make =
it easier. Just because I can see a feature is useful does not mean it dese=
rves to be part of the standard, or that we should disrupt currently workin=
g code to implement it, especially when a library solution is so obvious.</=
div></div></blockquote><div><br></div></div></div><div dir=3D"ltr"><div cla=
ss=3D"gmail_quote"><div>It's always going to be a matter of opinion whe=
ther the gains outweigh the costs. But first of all we need to maximize the=
gains and minimize the costs. We're still in the relatively early phas=
es of that exploitative work, with currently some new ideas being passed ar=
ound that could make it a lot more attractive than what you might have init=
ially envisioned. Secondly, C++ has never really been a language that shies=
away from features that may only have select use cases or are not foolproo=
f. So even if you don't think it "deserves" it, it might stil=
l be embraced by the standard.</div><div><br></div><div>I'm a curious a=
bout your "obvious" library solution though, although I fear it w=
ould just be another undesirable manual method.</div></div></div><div dir=
=3D"ltr"><div class=3D"gmail_quote"><div>=C2=A0</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"><div>I understand what you mean by register alloc=
ation, but I again do not find it to be in any way similar beyond superfici=
ally, and once again, register allocation is part of implementation not the=
standard. It is completely possible for a compiler to do no register alloc=
ation at all; the reason it can is because of the "as if" rule. Y=
ou want non-trivial destructors to be called out of order? Not allowed by t=
he "as if" rule, for very good reasons. Trying to hack it in usin=
g implementation details is a bad idea.</div></div></blockquote><div><br></=
div></div></div><div dir=3D"ltr"><div class=3D"gmail_quote"><div>Repeating =
that register allocation is part of the implementation is not going to dete=
r me in any way. It's one of the options for supporting eager destructi=
on. And while register allocation is not a literal part of the standard, I&=
#39;m going to repeat once more that it's only due to the standard'=
s specification that compilers are enabled to do it. Similarly we need a ch=
ange of the standard to accommodate eager destruction of objects. And that&=
#39;s true regardless of whether we decide to make it merely a hint and dep=
endent on the implementation, or more deterministic. It looks like you have=
a preference toward the latter. Perhaps you'd like to elaborate on tha=
t with some constructive arguments.</div></div></div><div dir=3D"ltr"><div =
class=3D"gmail_quote"><div>=C2=A0</div><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div =
dir=3D"ltr"><div>Guess that's "too bad" for you, then.</div><=
/div></blockquote><div><br></div></div></div><div dir=3D"ltr"><div class=3D=
"gmail_quote">I will gladly accept any outcome of this discussion.</div></d=
iv><div dir=3D"ltr"><div class=3D"gmail_quote"><div>=C2=A0</div><blockquote=
class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc soli=
d;padding-left:1ex"><div class=3D"gmail_extra"><br><div class=3D"gmail_quot=
e">On Mon, Aug 29, 2016 at 1:02 PM, Nicolas Capens <span dir=3D"ltr"><<a=
href=3D"mailto:nicolas.capens@gmail.com" target=3D"_blank">nicolas.capens@=
gmail.com</a>></span> wrote:<br><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 class=3D"gmail_quote"><span><div dir=3D"ltr">On Fri, Aug 26, =
2016 at 5:46 PM Ren Industries <<a href=3D"mailto:renindustries@gmail.co=
m" target=3D"_blank">renindustries@gmail.com</a>> wrote:<br></div><block=
quote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc=
solid;padding-left:1ex"><div dir=3D"ltr">That in no way demonstrates it is=
similar to register allocation, which is, again, a QOI issue.</div></block=
quote><div><br></div></span><div>My apologies. The example omitted how the =
equivalent scalar code would have its registers freed up for use by other v=
ariables after their last use. I thought that would be sufficiently clear. =
Here's an illustration of that:=C2=A0<a href=3D"http://compilers.cs.ucl=
a.edu/fernando/projects/puzzles/tutorial/" target=3D"_blank">http://compile=
rs.cs.ucla.edu/fernando/projects/puzzles/tutorial/</a>. The end of the live=
ranges corresponds to where I'd like the destructors of objects to be =
called. Let me know if the similarities are still not obvious to you and I&=
#39;ll create a more detailed side-by-side example if I find the time.</div=
><div><br></div><div>Anyway, yes, register allocation is a quality of imple=
mentation issue. One that is enabled by the standard allowing for it becaus=
e scalars having no side-effects on destruction. I want to enable that same=
freedom of optimization for objects that do have side-effects, by telling =
the compiler that we don't care about these side-effects to happen at t=
he end of the variable's scope.</div><span><div>=C2=A0</div><blockquote=
class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc soli=
d;padding-left:1ex"><div dir=3D"ltr">It is not necessarily the case that a =
compiler need do that, and I can think of at least a few counter examples. =
For example, there are projects that output C++ to javascript or java, whic=
h have no notion of register allocation as you point to it. These "mac=
hines" are perfectly valid C++ targets, yet have absolutely no notion =
of what you are talking about.</div></blockquote><div><br></div></span><div=
>I realize that. But I shouldn't have to care if a compiler strictly ne=
eds to do that today or not. I'm talking about adding a new feature to =
the language, and this may involve adding some new implementation requireme=
nts. If that causes some cross-compilers to no longer be able to support th=
is new version of C++ without some non-trivial effort, too bad. It's ce=
rtainly not my aim to make implementer's lives difficult, but I also do=
n't want to cripple or abandon the feature because of it.</div><span><d=
iv><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;b=
order-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Indeed, C=
++ supports a huge variety of applications. More than you know of, it seems=
..</div></div></blockquote><div><br></div></span><div>You're talking abo=
ut Emscripten and alike. That's implementation side. I was talking abou=
t applications written in C++. You seemed to see no practical uses for this=
feature, presumably because you hadn't encountered such an application=
before. Did my trivial example clarify that manual freeing of the resource=
s is not acceptable, or do you still disagree?</div><div><div><div>=C2=A0</=
div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-lef=
t:1px #ccc solid;padding-left:1ex"><div class=3D"gmail_extra"><div class=3D=
"gmail_quote">On Fri, Aug 26, 2016 at 3:21 PM, Nicolas Capens <span dir=3D"=
ltr"><<a href=3D"mailto:nicolas.capens@gmail.com" target=3D"_blank">nico=
las.capens@gmail.com</a>></span> wrote:<br><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex=
"><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><s=
pan>On Fri, Aug 26, 2016 at 1:16 PM, Ren Industries <span dir=3D"ltr"><<=
a href=3D"mailto:renindustries@gmail.com" target=3D"_blank">renindustries@g=
mail.com</a>></span> wrote:<br><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">Why is it such a terrible imposition to require=
manual interaction to enforce this behavior? I don't buy your argument=
that it is similar to register allocation; that's a QOI not a standard=
s issue.</div></blockquote><div><br></div></span><div>Consider this simple =
statement:</div><div><br></div><div>=C2=A0 =C2=A0 x =3D a * b * c;</div><di=
v><br></div><div>Assume they're all scalars, and a, b, and c are no lon=
ger used after this statement. That means liveness analysis will make their=
registers available for other variables, without you having to worry about=
it. But if instead these variables were huge matrices and you had to manua=
lly free their storage to minimize memory consumption, then it would look s=
omething like this:</div><div><br></div><div>=C2=A0 =C2=A0 Matrix t =3D a *=
b;</div><div>=C2=A0 =C2=A0 a.~Matrix();</div><div>=C2=A0 =C2=A0 b.~Matrix(=
);</div><div>=C2=A0 =C2=A0 x =3D t * c;</div><div>=C2=A0 =C2=A0 t.~Matrix()=
;</div><div>=C2=A0 =C2=A0 c.~Matrix();</div><div><br></div><div>Or if you w=
anted to do it with scopes:</div><div><br></div><div>=C2=A0 =C2=A0 {</div><=
div>=C2=A0 =C2=A0 Matrix t;</div><div>=C2=A0 =C2=A0 {</div><div>=C2=A0 =C2=
=A0 Matrix a =3D ...;</div><div>=C2=A0 =C2=A0 Matrix b =3D ...;</div><div>=
=C2=A0 =C2=A0 t =3D a * b;</div><div>=C2=A0 =C2=A0 }</div><div>=C2=A0 =C2=
=A0 Matrix c =3D ...;<br></div><div>=C2=A0 =C2=A0 x =3D t * c;</div><div>=
=C2=A0 =C2=A0 }</div><div><br></div><div>To me the original statement looks=
a whole lot easier to read and maintain than the two workarounds. And this=
is just a trivial example! It would become insane to do it for any realist=
ic data processing code.</div><div><br></div><div>Also I think that calling=
something a "terrible imposition" or not is highly subjective. M=
any recent C++ features solve issues that already had workarounds which som=
e considered acceptable but were unworkable for others. So please avoid bei=
ng prejudiced by your own experience and having no direct use for this your=
self. C++ supports a huge variety of applications.</div><div><br></div><div=
>I hope the above example illustrates that this is very similar to register=
allocation, and it's a standards issue that we don't get this beha=
vior today for non-scalar types.</div><div>=C2=A0</div><blockquote class=3D=
"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(2=
04,204,204);padding-left:1ex"><div><div><div class=3D"gmail_extra"><div cla=
ss=3D"gmail_quote"><div><div>On Fri, Aug 26, 2016 at 1:05 PM, Nicolas Capen=
s <span dir=3D"ltr"><<a href=3D"mailto:nicolas.capens@gmail.com" target=
=3D"_blank">nicolas.capens@gmail.com</a>></span> wrote:<br></div></div><=
blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-l=
eft:1px solid rgb(204,204,204);padding-left:1ex"><div><div><div dir=3D"ltr"=
><br><br><div class=3D"gmail_quote"><span><div dir=3D"ltr">On Wed, Aug 24, =
2016 at 4:22 PM Nevin Liber <<a href=3D"mailto:nevin@eviloverlord.com" t=
arget=3D"_blank">nevin@eviloverlord.com</a>> wrote:<br></div><blockquote=
class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px so=
lid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr">On 24 August 2016 a=
t 15:16, <span dir=3D"ltr"><<a href=3D"mailto:nicolas.capens@gmail.com"=
target=3D"_blank">nicolas.capens@gmail.com</a>></span> wrote:<br></div>=
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><blo=
ckquote 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>The cod=
e would become littered with braces if you want to limit the scope of each =
object to its miminal range,</div></div></blockquote><div><br></div></div><=
/div></div><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_=
quote"><div>I don't understand why you would want to do that.=C2=A0 Cou=
ld you elaborate?</div></div></div></div></blockquote><div><br></div></span=
><div>Certainly. I wrote down three practical use cases <a href=3D"https://=
groups.google.com/a/isocpp.org/forum/#!msg/std-proposals/IUxA4cx8yHc/yKNqKl=
8hDgAJ" target=3D"_blank">here</a>.</div><span><div>=C2=A0</div><blockquote=
class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px so=
lid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail=
_extra"><div class=3D"gmail_quote"><div>And if the objects are truly indepe=
ndent and have no observable effect, can't a compiler do that under the=
as-if rule?</div></div></div></div></blockquote><div><br></div></span><div=
>The problem is that the objects I'm using do have side-effects, so the=
compiler won't attempt to shorten their lifespan. But in my use cases =
the side effects are "self-contained", i.e. you could treat them =
as scalars and destruct them right after their last use.</div><span><div>=
=C2=A0</div><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"l=
tr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div>Also, if you=
wish to have a lifetime shorter than a scope for an object of type T, you =
can just use std::optional<T>.</div></div></div></div></blockquote><d=
iv><br></div></span><div>How would that work, without requiring manual acti=
ons to destruct it?</div><span><div>=C2=A0</div><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 class=3D"gmail_extra"><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"><div d=
ir=3D"ltr"><div>Fortunately we don't, because today's compilers do =
liveness analysis to optimize register allocation.</div></div></blockquote>=
<div><br></div></div></div></div><div dir=3D"ltr"><div class=3D"gmail_extra=
"><div class=3D"gmail_quote"><div>One of the huge benefits to C++ is that d=
estruction happens at well defined times.=C2=A0 This would break that.</div=
></div></div></div></blockquote><div><br></div></span><div>Yes, in many cas=
es it will be preferable to keep the well defined behavior of implicitly ca=
lling the destructor at the end of the variable's scope. The opt-in fea=
ture I'm proposing should be used sparingly and cautiously. But when us=
ed by a well written framework it should be foolproof for the users of the =
framework, and offer them significant benefits.</div><div>=C2=A0</div><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:=
1px solid rgb(204,204,204);padding-left:1ex"><span><div dir=3D"ltr"><div cl=
ass=3D"gmail_extra">-- <br><div data-smartmail=3D"gmail_signature"><div dir=
=3D"ltr"><div><div dir=3D"ltr"><div>=C2=A0Nevin ":-)" Liber=C2=A0=
<mailto:<a href=3D"mailto:nevin@eviloverlord.com" target=3D"_blank">nev=
in@eviloverlord.com</a>> =C2=A0<a href=3D"tel:%2B1-847-691-1404" value=
=3D"+18476911404" target=3D"_blank">+1-847-691-1404</a></div></div></div></=
div></div>
</div></div>
<p></p>
-- <br></span>
You received this message because you are subscribed to a topic in the Goog=
le Groups "ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/IUxA4cx8yHc/unsubscribe" target=3D"_blan=
k">https://groups.google.com/a/isocpp.org/d/topic/std-proposals/IUxA4cx8yHc=
/unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a href=
=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_blank">std-prop=
osals+unsubscribe@isocpp.org</a>.<span><br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">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/CAGg_6%2BM3M43y_8jTg4mXce1sz7UQ5kzSkO=
VqL3F_nYEe-ogzNA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r" target=3D"_blank">https://groups.google.com/a/isocpp.org/d/msgid/std-pro=
posals/CAGg_6%2BM3M43y_8jTg4mXce1sz7UQ5kzSkOVqL3F_nYEe-ogzNA%40mail.gmail.c=
om</a>.<br>
</span></blockquote></div></div></div></div><span>
<p></p>
-- <br><span>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br></span>
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" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<span><br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></span></span>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAE7XuEVobd1QW2jJYW-hGTLTPgQxRJM-QkL9=
jNovOkhaaoXQEw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
target=3D"_blank">https://groups.google.com/a/isocpp.org/d/msgid/std-propo=
sals/CAE7XuEVobd1QW2jJYW-hGTLTPgQxRJM-QkL9jNovOkhaaoXQEw%40mail.gmail.com</=
a>.<br>
</blockquote></div><br></div><span>
<p></p>
-- <br>
You received this message because you are subscribed to a topic in the Goog=
le Groups "ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/IUxA4cx8yHc/unsubscribe" target=3D"_blan=
k">https://groups.google.com/a/isocpp.org/d/topic/std-proposals/IUxA4cx8yHc=
/unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a href=
=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_blank">std-prop=
osals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></span></div></div=
>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAMD6iD_8zsoqfYdUsY%2BQe_QNvzFsH4c9uU=
jNYzw5BRFiLQRE%2BQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoo=
ter" target=3D"_blank">https://groups.google.com/a/isocpp.org/d/msgid/std-p=
roposals/CAMD6iD_8zsoqfYdUsY%2BQe_QNvzFsH4c9uUjNYzw5BRFiLQRE%2BQ%40mail.gma=
il.com</a>.<br>
</blockquote></div><br></div></div>
</blockquote></div><br></div>
</blockquote></div></div></div></div>
</blockquote></div><br></div>
</blockquote></div></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/CAE7XuEW%2BcRoF_T59wS53M%3DQrB85GOGyd=
UXWoBfcmauKJTc5tAA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAE7XuEW%2BcR=
oF_T59wS53M%3DQrB85GOGydUXWoBfcmauKJTc5tAA%40mail.gmail.com</a>.<br />
--001a1141136e7eeafa053b4a914d--
.
Author: Nicolas Capens <nicolas.capens@gmail.com>
Date: Tue, 30 Aug 2016 15:20:42 +0000
Raw View
--001a1147b01cc3ea6f053b4b869c
Content-Type: text/plain; charset=UTF-8
On Mon, Aug 29, 2016 at 2:46 PM Nicol Bolas <jmckesson@gmail.com> wrote:
> 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> 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.
>
Except I didn't argue about using a name that could make it seem more
palatable. Like I said, with lazy vs. eager one isn't inherently better
than the other. But premature is always a bad thing. So insisting on using
that would be a pejorative word game. And again, I'm open to a better name.
Just don't use one that would cause a negative prejudice because that could
damage having a constructive discussion.
> 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.
>
It's my proposal. Making object lifetimes somewhat analogous to register
lifetimes is what I'm after. You're very welcome to have your own proposal.
Just don't conflate it with mine and dictate what I can or cannot want.
With that out of the way, note that it's only one of the two options.
Either we use eager destruction as a hint, so it does become an
implementation detail. You seem to be liking
<https://groups.google.com/a/isocpp.org/d/msg/std-proposals/IUxA4cx8yHc/Q2kIq3lHEQAJ>
that idea. But that goes against your "the point in time when an automatic
variable is destroyed should not be a *mystery*" mantra. Either way perhaps
the analogy of register allocation isn't so crazy after all?
The second option is to have a deterministic "last use" within the local
scope, potentially with restrictions on storing references to avoid
incorrect usage. Admittedly this option would be less analogous to register
allocation.
> 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.
>
First of all, there's no law that dictates that legacy code under new
conditions still has to have the same semantics. Something as simple as a
+ b would for a C developer be nothing other than an addition of scalars,
while in C++ it can mean absolutely anything due to operator overloading.
That can be badly abused, but it can also be a very powerful abstraction.
So I don't think not breaking your template example is a strict necessity.
Secondly, we could explore whether we can make it a compilation error to
use this code with an eagerly destructed type/variable.
> 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.
>
I beg to differ. Compilers can know the dependency caused by this
reference, through static analysis. And they can be conservative about it
if insufficient information is not available. C++ just chose not to support
temporary lifetime extension. But we shouldn't have to restrict ourselves
to such an aggressive approach for future features. Eager destruction can
either also be aggressive and not support the use of any references after
the last local use (without or without compiler warning/error), or we can
make it conservative and merely a hint so that it's up to the compiler
implementation how eagerly the destructor gets called.
> Your framework cannot prevent "incorrect" use of the type. So your
> proposal is flawed.
>
Many C++ features can be used incorrectly with nothing to prevent you from
it. That hasn't stopped them from making it into the standard. That said,
if this is really a major concern of eager destruction, then we should
explore how we can make some or all of the incorrect uses a compiler error,
or, it means we have to go with the conservative option.
--
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/CAE7XuEU1qjr6dLqzKUyAQSGVLuCwFMykr4G_6GFP77AGEwL-xQ%40mail.gmail.com.
--001a1147b01cc3ea6f053b4b869c
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Mon=
, Aug 29, 2016 at 2:46 PM Nicol Bolas <<a href=3D"mailto:jmckesson@gmail=
..com">jmckesson@gmail.com</a>> wrote:<br></div><blockquote class=3D"gmai=
l_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left=
:1ex"><div dir=3D"ltr">On Monday, August 29, 2016 at 11:22:42 AM UTC-4, Nic=
olas Capens wrote:</div><div dir=3D"ltr"><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><div class=3D"gmail_quote">On Wed, Aug 24, 2016=
at 6:05 PM, Nicol Bolas <span dir=3D"ltr"><<a rel=3D"nofollow">jmck...@=
gmail.com</a>></span> wrote:<br><blockquote class=3D"gmail_quote" style=
=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><span>On Wednesday, August 24, 2016 at 5:17:26 PM UTC-4, <a>nicola=
s...@gmail.com</a> 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">On Wednesday, August 24, 2016 at 3:19:24 PM UTC-4, Matt Calabrese =
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"><div><div cl=
ass=3D"gmail_quote">On Wed, Aug 24, 2016 at 11:51 AM, <span dir=3D"ltr">&l=
t;<a rel=3D"nofollow">nicolas...@gmail.com</a>></span> wrote:<br><blockq=
uote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc =
solid;padding-left:1ex"><div dir=3D"ltr"><div>Hi all,</div><div><br></div>I=
'd like to propose a new kind of destructor that gets called after a lo=
cal object's last use, instead of at the end of its scope.<div><br></di=
v><div>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 resul=
t in more efficient programs.</div><div><br></div><div>Currently such optim=
ization can only be achieved by explicitly releasing the resources, which i=
s inconvenient, bug prone, and reduces readability. Limiting the scope with=
extra braces or by putting the operations in a subroutine also often isn&#=
39;t a desirable workaround. Note that compilers have been doing liveness a=
nalysis for register allocation and stack compaction for a very long time a=
nd we take these optimizations for granted. I'd like to see it get exte=
nded to heap memory and other resources as well.</div><div><span style=3D"l=
ine-height:17px"><br></span></div><div>The s<span style=3D"line-height:17px=
">yntax 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();".</span></div><div><span style=3D"line-height:17px"><br><=
/span></div><div><span style=3D"line-height:17px">Thoughts?</span></div></d=
iv></blockquote><div><br></div><div>While I would like C++ to eventually ge=
t a way to do the equivalent of this in some form (more generally, I want d=
estructive move, which is related to this even though it may not be immedia=
tely obvious),</div></div></div></div></blockquote><div><br></div><div>Yes,=
a destructive assignment could count as a last use of its previous value a=
nd call the destructor that I'm proposing. I'd also like it to be c=
alled after the last use as a source argument too though.</div><div>=C2=A0<=
/div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;=
border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><div cla=
ss=3D"gmail_quote"><div>I do not think that the appropriate place to notate=
the premature destruction is on the destructor declaration. Instead, I bel=
ieve it needs to be explicit at the usage-site. This is primarily because w=
e are in a language where side-effects matter.</div></div></div></div></blo=
ckquote><div><br></div><div>I wouldn't call it premature destruction. E=
ager instead of today's lazy destruction at the end of the scope, seems=
like a better description to me.</div></div></blockquote></span><div><br>P=
laying word games doesn't change the fact that the standard makes it cl=
ear that destruction of an automatic object happens in a single, well-defin=
ed place. Your proposal wants to *transparently* change 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 class=3D"gmail_quote"><div=
>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 neutr=
al. Other suggestions welcome.</div></div></div></div></div></blockquote></=
div><div dir=3D"ltr"><div><br>The term "playing word games" 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></div></div></blockquote><div><br></div><div>E=
xcept I didn't argue about using a name that could make it seem more pa=
latable. Like I said, with lazy vs. eager one isn't inherently better t=
han the other. But premature is always a bad thing. So insisting on using t=
hat would be a pejorative word game. And again, I'm open to a better na=
me. Just don't use one that would cause a negative prejudice because th=
at could damage having a constructive discussion.</div><div>=C2=A0</div><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #=
ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div></div><div dir=3D"l=
tr"><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;b=
order-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div dir=3D"lt=
r"><div><div class=3D"gmail_quote"><div></div><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex=
"><div dir=3D"ltr"><div>You can explicitly reset smart pointers; you can ex=
plicitly close streams. And for moveable types that don't offer such fe=
atures, Magnus gave a great answer:<br><br><div style=3D"background-color:r=
gb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-wid=
th: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</spa=
n><span style=3D"color:#660">::</span><span style=3D"color:#000">move</span=
><span style=3D"color:#660">(</span><span style=3D"color:#000">auto_val</sp=
an><span style=3D"color:#660">));</span></div></code></div><br>That works f=
or pretty much any moveable `Object` type that represents a resource.<br><b=
r>The point in time when an automatic 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.<br></div></div></blockquote><div><br></di=
v><div>Why? We don't question whether a register is still in use or not=
, don't we?</div></div></div></div></div></blockquote></div><div dir=3D=
"ltr"><div><br>I don't know why you keep bringing up registers. Object =
lifetimes <i>are not like registers</i> in any way, shape, or form. Registe=
rs are an <i>implementation detail</i> of a particular machine/compiler. Ob=
ject lifetimes are specified by the standard.<br><br>This is a false analog=
y; please stop using it.<br></div></div></blockquote><div><br></div><div>It=
's my proposal. Making object lifetimes somewhat analogous to register =
lifetimes is what I'm after. You're very welcome to have your own p=
roposal. Just don't conflate it with mine and dictate what I can or can=
not want.</div><div><br></div><div>With that out of the way, note that it&#=
39;s only one of the two options. Either we use eager destruction as a hint=
, so it does become an implementation detail. You seem to be <a href=3D"htt=
ps://groups.google.com/a/isocpp.org/d/msg/std-proposals/IUxA4cx8yHc/Q2kIq3l=
HEQAJ">liking</a> that idea. But that goes against your "t<span style=
=3D"line-height:1.5">he point in time when an automatic variable is destroy=
ed should not be a</span><span class=3D"inbox-inbox-Apple-converted-space" =
style=3D"line-height:1.5">=C2=A0</span><i style=3D"line-height:1.5">mystery=
</i><span style=3D"line-height:1.5">" mantra. Either way perhaps the a=
nalogy of register allocation isn't so crazy after all?</span></div><di=
v><span style=3D"line-height:1.5"><br></span></div><div><span style=3D"line=
-height:1.5">The second option is to have a deterministic "last use&qu=
ot; within the local scope, potentially with restrictions on storing refere=
nces to avoid incorrect usage. Admittedly this option would be less analogo=
us to register allocation.</span></div><div>=C2=A0</div><blockquote class=
=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr"><div></div></div><div dir=3D"ltr"><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 dir=3D"ltr"><div><div c=
lass=3D"gmail_quote"><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><=
/div><span><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>So=
I want to make it clear to the compiler that I'd like it to be destroy=
ed eagerly, and not just for this one but for every instance. It's a pr=
operty of the class itself that I want it's destructor to be called eag=
erly. If I don't want that behavior I can simply use an equivalent clas=
s without eager destructor.</div></div></blockquote></span><div><br>You'=
;ve provided a very good reason not to do this at all. We do not want to en=
courage the proliferation of types that differ <i>only</i> by the presence =
or absence of "eager destruction". We don't want `eager_uniqu=
e_ptr` or `eager_ifstream` or `eager_vector` or whatever.<br></div></div></=
blockquote><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-p=
roposals/IUxA4cx8yHc/yKNqKl8hDgAJ" rel=3D"nofollow" target=3D"_blank">my ex=
amples</a>. 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.</div></div></div></div></div></blockquote></div><div=
dir=3D"ltr"><div><br>Your interface cannot stop people from using the obje=
ct "incorrectly". Consider the template example I used elsewhere:=
</div></div><div dir=3D"ltr"><div><br><br><div style=3D"background-color:rg=
b(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-widt=
h:1px;word-wrap:break-word"><code><div><span style=3D"color:#000">T t </spa=
n><span style=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">auto</span><span style=3D"color:#000"> tpl </span=
><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> forward_a=
s_tuple</span><span style=3D"color:#660">(</span><span style=3D"color:#000"=
>t</span><span style=3D"color:#660">);</span><span style=3D"color:#000"><br=
></span><span style=3D"color:#800">//do something with tpl.</span><span sty=
le=3D"color:#000"><br></span></div></code></div><br></div></div><div dir=3D=
"ltr"><div>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.<br><br>There is nothing you as the creator o=
f the type `T` to make it so that `T`'s interface will <i>prevent</i> s=
omeone from doing this.<br></div></div></blockquote><div><br></div><div>Fir=
st of all, there's no law that dictates that legacy code under new cond=
itions still has to have the same semantics. Something as simple as <font f=
ace=3D"monospace">a +=C2=A0b</font> would for a C developer be nothing othe=
r than an addition of scalars, while in C++ it can mean absolutely anything=
due to operator overloading. That can be badly abused, but it can also be =
a very powerful abstraction. So I don't think not breaking your templat=
e example is a strict necessity.</div><div><br></div><div>Secondly, we coul=
d explore whether we can make it a compilation error to use this code with =
an eagerly destructed type/variable.</div><div>=C2=A0</div><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;pad=
ding-left:1ex"><div dir=3D"ltr"><div>And there are no tricks the compiler c=
an 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 i=
n the <i>general</i> case. To the compiler, a non-inline function is a comp=
lete black box; it knows the inputs and it knows the outputs. But it doesn&=
#39;t know what happens in the middle.<br><br>This problem is fundamentally=
identical to the temporary lifetime extension problem. Namely, that this w=
orks:<br><br><div style=3D"background-color:rgb(250,250,250);border-color:r=
gb(187,187,187);border-style:solid;border-width:1px;word-wrap:break-word"><=
code><div><span style=3D"color:#008">const</span><span style=3D"color:#000"=
> </span><span style=3D"color:#008">auto</span><span style=3D"color:#000"> =
</span><span style=3D"color:#660">&</span><span style=3D"color:#000">st=
r </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> s=
td</span><span style=3D"color:#660">::</span><span style=3D"color:#008">str=
ing</span><span style=3D"color:#660">(...);</span><span style=3D"color:#000=
"><br></span><span style=3D"color:#800">//use str</span><span style=3D"colo=
r:#000"><br></span></div></code></div><br>While this does not:<br><br><div =
style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);bo=
rder-style:solid;border-width:1px;word-wrap:break-word"><code><div><span st=
yle=3D"color:#008">const</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#008">auto</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">&</span><span style=3D"color:#000">str </span><span sty=
le=3D"color:#660">=3D</span><span style=3D"color:#000"> std</span><span sty=
le=3D"color:#660">::</span><span style=3D"color:#008">string</span><span st=
yle=3D"color:#660">(...).</span><span style=3D"color:#000">c_str</span><spa=
n style=3D"color:#660">();</span><span style=3D"color:#000"><br></span><spa=
n style=3D"color:#800">//use str</span><span style=3D"color:#000"><br></spa=
n></div></code></div><br>Why doesn't this work? Because the compiler <i=
>cannot know</i> that `c_str` returns a pointer/reference into something co=
ntrolled by the temporary. Therefore, the compiler must assume that the fun=
ction's return value is independent of the lifetime of the parameter/th=
is. This could have worked if `c_str` were a data member. But because it=
9;s a member function, it will not extend the lifetime of the temporary.<br=
><br>Your problem is the exact same thing, just 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 contains a pointer/reference to an a=
rgument or an element of an argument.<br></div></div></blockquote><div><br>=
</div><div>I beg to differ. Compilers can know the dependency caused by thi=
s reference, through static analysis. And they can be conservative about it=
if insufficient information is not available. C++ just chose not to suppor=
t temporary lifetime extension. But we shouldn't have to restrict ourse=
lves to such an aggressive approach for future features. Eager destruction =
can either also be aggressive and not support the use of any references aft=
er the last local use (without or without compiler warning/error), or we ca=
n make it conservative and merely a hint so that it's up to the compile=
r implementation how eagerly the destructor gets called.</div><div>=C2=A0</=
div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-lef=
t:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Your framework can=
not prevent "incorrect" use of the type. So your proposal is flaw=
ed.<br></div></div></blockquote><div><br></div><div>Many C++ features can b=
e used incorrectly with nothing to prevent you from it. That hasn't sto=
pped them from making it into the standard. That said, if this is really a =
major concern of eager destruction, then we should explore how we can make =
some or all of the incorrect uses a compiler error, or, it means we have to=
go with the conservative option.=C2=A0</div></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/CAE7XuEU1qjr6dLqzKUyAQSGVLuCwFMykr4G_=
6GFP77AGEwL-xQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAE7XuEU1qjr6dLqz=
KUyAQSGVLuCwFMykr4G_6GFP77AGEwL-xQ%40mail.gmail.com</a>.<br />
--001a1147b01cc3ea6f053b4b869c--
.
Author: Patrice Roy <patricer@gmail.com>
Date: Tue, 30 Aug 2016 20:53:32 -0400
Raw View
--94eb2c12474ed3963d053b5386e9
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
It's an interesting optimization problem, I think. My first reflex reading
all this (apart from just writing smaller functions and make the problem
disappear, but I know people don't always do that) was to do manual
move-from or apply some other technique (maybe a std:: function like
std::last_use(T && arg) that essentially does auto whatever =3D
std::move(arg); along with some manoeuver to avoid unused variable
warnings) and suggest std::last_use() users to think about move semantics a
lot.
The OP's opinion that manual markup is as tedious as manual scoping (or
refactoring) and that static analysis should take over is interesting, but
not something I'm confident enough to mandate on compiler writers (unless
they, themselves, say they can do it). On the other hand, there might be
compilers that can confidently do it, in some cases at least. Thus, should
the OP want to go ahead, my feeling (and I'm not a compiler writer, so they
can correct me all they like and they'll be right :) ) would be to go with
an attribute on variable / argument declaration in this case. It would
allow markup of individual variables, and would make it Ok to be taken as
an optimistic suggestion from the perspective of compilers that can't
really do it, or in the cases where they cannot determine the point of last
use clearly from the source code.
I'm guessing users of this attribute would mark costly variables on which
they'd like eager destruction only, and would accept the longer compilation
times associated with the liveliness analysis involved. I'm also guessing
that people writing smaller functions would essentially not need this, but
that it could be useful for those who prefer not to refactor their code (or
don't know how to, or just would prefer to think of other things as they
see programming as a means to an end, or...). Should a compiler not be able
to perform the task suggested by this attribute, the =C2=ABmanual=C2=BB opt=
ion
remains open.
It's what comes to my mind right now. I don't think anything stronger that
this could be standardized anyway (it delves into issues like dynamic
linking and others where the standard doesn't really tread all that much :)
). Hope it's useful, half-baked as it is.
2016-08-30 11:20 GMT-04:00 Nicolas Capens <nicolas.capens@gmail.com>:
>
>
> On Mon, Aug 29, 2016 at 2:46 PM Nicol Bolas <jmckesson@gmail.com> wrote:
>
>> 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> wrote:
>>>
>>>> On Wednesday, August 24, 2016 at 5:17:26 PM UTC-4, nicolas...@gmail.co=
m
>>>> 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 represent=
s 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 redu=
ces
>>>>>>> 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 alloc=
ation
>>>>>>> and stack compaction for a very long time and we take these optimiz=
ations
>>>>>>> for granted. I'd like to see it get extended to heap memory and oth=
er
>>>>>>> resources as well.
>>>>>>>
>>>>>>> The syntax for this could be an annotation of the destructor
>>>>>>> declaration with a keyword, symbol, or attribute. For example, "aut=
o
>>>>>>> ~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 l=
ike 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 i=
n 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 descrip=
tion
>>>>> 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 nam=
e
>> of something in order to make it seem more palatable. So you seem to be
>> admitting to playing word games while simultaneously denying it.
>>
>
> Except I didn't argue about using a name that could make it seem more
> palatable. Like I said, with lazy vs. eager one isn't inherently better
> than the other. But premature is always a bad thing. So insisting on usin=
g
> that would be a pejorative word game. And again, I'm open to a better nam=
e.
> Just don't use one that would cause a negative prejudice because that cou=
ld
> damage having a constructive discussion.
>
>
>> 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 b=
e
>>>> 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 *implem=
entation
>> detail* of a particular machine/compiler. Object lifetimes are specified
>> by the standard.
>>
>> This is a false analogy; please stop using it.
>>
>
> It's my proposal. Making object lifetimes somewhat analogous to register
> lifetimes is what I'm after. You're very welcome to have your own proposa=
l.
> Just don't conflate it with mine and dictate what I can or cannot want.
>
> With that out of the way, note that it's only one of the two options.
> Either we use eager destruction as a hint, so it does become an
> implementation detail. You seem to be liking
> <https://groups.google.com/a/isocpp.org/d/msg/std-proposals/IUxA4cx8yHc/Q=
2kIq3lHEQAJ>
> that idea. But that goes against your "the point in time when an
> automatic variable is destroyed should not be a *mystery*" mantra. Either
> way perhaps the analogy of register allocation isn't so crazy after all?
>
> The second option is to have a deterministic "last use" within the local
> scope, potentially with restrictions on storing references to avoid
> incorrect usage. Admittedly this option would be less analogous to regist=
er
> allocation.
>
>
>> 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/IUxA4=
cx8yHc/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 =3D ...
>> auto tpl =3D 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++. Templ=
ate
>> 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.
>>
>
> First of all, there's no law that dictates that legacy code under new
> conditions still has to have the same semantics. Something as simple as a
> + b would for a C developer be nothing other than an addition of scalars,
> while in C++ it can mean absolutely anything due to operator overloading.
> That can be badly abused, but it can also be a very powerful abstraction.
> So I don't think not breaking your template example is a strict necessity=
..
>
> Secondly, we could explore whether we can make it a compilation error to
> use this code with an eagerly destructed type/variable.
>
>
>> 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 =3D std::string(...);
>> //use str
>>
>> While this does not:
>>
>> const auto &str =3D 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 worke=
d
>> if `c_str` were a data member. But because it's a member function, it wi=
ll
>> not extend the lifetime of the temporary.
>>
>> Your problem is the exact same thing, just for named variables instead o=
f
>> 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.
>>
>
> I beg to differ. Compilers can know the dependency caused by this
> reference, through static analysis. And they can be conservative about it
> if insufficient information is not available. C++ just chose not to suppo=
rt
> temporary lifetime extension. But we shouldn't have to restrict ourselves
> to such an aggressive approach for future features. Eager destruction can
> either also be aggressive and not support the use of any references after
> the last local use (without or without compiler warning/error), or we can
> make it conservative and merely a hint so that it's up to the compiler
> implementation how eagerly the destructor gets called.
>
>
>> Your framework cannot prevent "incorrect" use of the type. So your
>> proposal is flawed.
>>
>
> Many C++ features can be used incorrectly with nothing to prevent you fro=
m
> it. That hasn't stopped them from making it into the standard. That said,
> if this is really a major concern of eager destruction, then we should
> explore how we can make some or all of the incorrect uses a compiler erro=
r,
> or, it means we have to go with the conservative option.
>
> --
> 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/CAE7XuEU1qjr6dLqzKUyAQSGVLuCwF
> Mykr4G_6GFP77AGEwL-xQ%40mail.gmail.com
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAE7XuEU1qj=
r6dLqzKUyAQSGVLuCwFMykr4G_6GFP77AGEwL-xQ%40mail.gmail.com?utm_medium=3Demai=
l&utm_source=3Dfooter>
> .
>
--=20
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 e=
mail 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/CAKiZDp2mOy1cYfHys4A%3D5GfR0-1bidoKheyOo2oWVCXEw=
_RteQ%40mail.gmail.com.
--94eb2c12474ed3963d053b5386e9
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div><div><div>It's an interesting optimization proble=
m, I think. My first reflex reading all this (apart from just writing small=
er functions and make the problem disappear, but I know people don't al=
ways do that) was to do manual move-from or apply some other technique (may=
be a std:: function like std::last_use(T && arg) that essentially d=
oes auto whatever =3D std::move(arg); along with some manoeuver to avoid un=
used variable warnings) and suggest std::last_use() users to think about mo=
ve semantics a lot.<br><br></div>The OP's opinion that manual markup is=
as tedious as manual scoping (or refactoring) and that static analysis sho=
uld take over is interesting, but not something I'm confident enough to=
mandate on compiler writers (unless they, themselves, say they can do it).=
On the other hand, there might be compilers that can confidently do it, in=
some cases at least. Thus, should the OP want to go ahead, my feeling (and=
I'm not a compiler writer, so they can correct me all they like and th=
ey'll be right :) ) would be to go with an attribute on variable / argu=
ment declaration in this case. It would allow markup of individual variable=
s, and would make it Ok to be taken as an optimistic suggestion from the pe=
rspective of compilers that can't really do it, or in the cases where t=
hey cannot determine the point of last use clearly from the source code.<br=
><br></div>I'm guessing users of this attribute would mark costly varia=
bles on which they'd like eager destruction only, and would accept the =
longer compilation times associated with the liveliness analysis involved. =
I'm also guessing that people writing smaller functions would essential=
ly not need this, but that it could be useful for those who prefer not to r=
efactor their code (or don't know how to, or just would prefer to think=
of other things as they see programming as a means to an end, or...). Shou=
ld a compiler not be able to perform the task suggested by this attribute, =
the =C2=ABmanual=C2=BB option remains open.<br><br></div>It's what come=
s to my mind right now. I don't think anything stronger that this could=
be standardized anyway (it delves into issues like dynamic linking and oth=
ers where the standard doesn't really tread all that much :) ). Hope it=
's useful, half-baked as it is.<br></div><div class=3D"gmail_extra"><br=
><div class=3D"gmail_quote">2016-08-30 11:20 GMT-04:00 Nicolas Capens <span=
dir=3D"ltr"><<a href=3D"mailto:nicolas.capens@gmail.com" target=3D"_bla=
nk">nicolas.capens@gmail.com</a>></span>:<br><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"><br><br><div class=3D"gmail_quote"><span class=3D""><d=
iv dir=3D"ltr">On Mon, Aug 29, 2016 at 2:46 PM Nicol Bolas <<a href=3D"m=
ailto:jmckesson@gmail.com" target=3D"_blank">jmckesson@gmail.com</a>> wr=
ote:<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 Monday, Au=
gust 29, 2016 at 11:22:42 AM UTC-4, Nicolas Capens wrote:</div><div dir=3D"=
ltr"><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><div cla=
ss=3D"gmail_quote">On Wed, Aug 24, 2016 at 6:05 PM, Nicol Bolas <span dir=
=3D"ltr"><<a rel=3D"nofollow">jmck...@gmail.com</a>></span> wrote:<br=
><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1=
px #ccc solid;padding-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:<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">On Wednesday, August 24, 201=
6 at 3:19:24 PM UTC-4, Matt Calabrese wrote:<blockquote class=3D"gmail_quot=
e" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><div dir=3D"ltr"><div><div class=3D"gmail_quote">On Wed, Aug 24, 2=
016 at 11:51 AM, <span dir=3D"ltr"><<a rel=3D"nofollow">nicolas...@gmai=
l.com</a>></span> wrote:<br><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>Hi all,</div><div><br></div>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.<div><br></div><div>The use of this would be to fr=
ee resources held by the object sooner. This could be heap memory, file han=
dles, mutex locks, etc. Releasing them as soon as we're done with the o=
bject that represents them would result in more efficient programs.</div><d=
iv><br></div><div>Currently such optimization can only be achieved by expli=
citly releasing the resources, which is inconvenient, bug prone, and reduce=
s readability. Limiting the scope with extra braces or by putting the opera=
tions in a subroutine also often isn't a desirable workaround. Note tha=
t compilers have been doing liveness analysis for register allocation and s=
tack compaction for a very long time and we take these optimizations for gr=
anted. I'd like to see it get extended to heap memory and other resourc=
es as well.</div><div><span style=3D"line-height:17px"><br></span></div><di=
v>The s<span style=3D"line-height:17px">yntax for this could be an annotati=
on of the destructor declaration with a keyword, symbol, or attribute. For =
example, "auto ~Object();", "volatile ~Object();", &quo=
t;~~Object();", or "[[eager]] ~Object();".</span></div><div>=
<span style=3D"line-height:17px"><br></span></div><div><span style=3D"line-=
height:17px">Thoughts?</span></div></div></blockquote><div><br></div><div>W=
hile 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),</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'm p=
roposing. I'd also like it to be called after the last use as a source =
argument too though.</div><div>=C2=A0</div><blockquote class=3D"gmail_quote=
" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-le=
ft:1ex"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div>I do not thin=
k that the appropriate place to notate the premature destruction is on the =
destructor declaration. Instead, I believe it needs to be explicit at the u=
sage-site. This is primarily because we are in a language where side-effect=
s matter.</div></div></div></div></blockquote><div><br></div><div>I wouldn&=
#39;t call it premature destruction. Eager instead of today's lazy dest=
ruction at the end of the scope, seems like a better description to me.</di=
v></div></blockquote></span><div><br>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 *tra=
nsparently* change that location based on something in the type of that obj=
ect.<br></div></div></blockquote><div><br></div></div></div><div dir=3D"ltr=
"><div><div class=3D"gmail_quote"><div>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.</div><=
/div></div></div></div></blockquote></div><div dir=3D"ltr"><div><br>The ter=
m "playing word games" refers to making an argument about the nam=
e of something in order to make it seem more palatable. So you seem to be a=
dmitting to playing word games while simultaneously denying it.<br></div></=
div></blockquote><div><br></div></span><div>Except I didn't argue about=
using a name that could make it seem more palatable. Like I said, with laz=
y vs. eager one isn't inherently better than the other. But premature i=
s always a bad thing. So insisting on using that would be a pejorative word=
game. And again, I'm open to a better name. Just don't use one tha=
t would cause a negative prejudice because that could damage having a const=
ructive discussion.</div><span class=3D""><div>=C2=A0</div><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;pad=
ding-left:1ex"><div dir=3D"ltr"><div></div></div><div dir=3D"ltr"><blockquo=
te class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1p=
x #ccc solid;padding-left: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;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D=
"ltr"><div>You can explicitly reset smart pointers; you can explicitly clos=
e streams. And for moveable types that don't offer such features, Magnu=
s gave a great answer:<br><br><div style=3D"background-color:rgb(250,250,25=
0);border-color:rgb(187,187,187);border-style:solid;border-width:1px;word-w=
rap:break-word"><code><div><span style=3D"color:#606">Object</span><span st=
yle=3D"color:#660">(</span><span style=3D"color:#000">std</span><span style=
=3D"color:#660">::</span><span style=3D"color:#000">move</span><span style=
=3D"color:#660">(</span><span style=3D"color:#000">auto_val</span><span sty=
le=3D"color:#660">));</span></div></code></div><br>That works for pretty mu=
ch any moveable `Object` type that represents a resource.<br><br>The point =
in time when an automatic 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.<br></div></div></blockquote><div><br></div><div>Why? =
We don't question whether a register is still in use or not, don't =
we?</div></div></div></div></div></blockquote></div><div dir=3D"ltr"><div><=
br>I don't know why you keep bringing up registers. Object lifetimes <i=
>are not like registers</i> in any way, shape, or form. Registers are an <i=
>implementation detail</i> of a particular machine/compiler. Object lifetim=
es are specified by the standard.<br><br>This is a false analogy; please st=
op using it.<br></div></div></blockquote><div><br></div></span><div>It'=
s my proposal. Making object lifetimes somewhat analogous to register lifet=
imes is what I'm after. You're very welcome to have your own propos=
al. Just don't conflate it with mine and dictate what I can or cannot w=
ant.</div><div><br></div><div>With that out of the way, note that it's =
only one of the two options. Either we use eager destruction as a hint, so =
it does become an implementation detail. You seem to be <a href=3D"https://=
groups.google.com/a/isocpp.org/d/msg/std-proposals/IUxA4cx8yHc/Q2kIq3lHEQAJ=
" target=3D"_blank">liking</a> that idea. But that goes against your "=
t<span style=3D"line-height:1.5">he point in time when an automatic variabl=
e is destroyed should not be a</span><span style=3D"line-height:1.5">=C2=A0=
</span><i style=3D"line-height:1.5">mystery</i><span style=3D"line-height:1=
..5">" mantra. Either way perhaps the analogy of register allocation is=
n't so crazy after all?</span></div><div><span style=3D"line-height:1.5=
"><br></span></div><div><span style=3D"line-height:1.5">The second option i=
s to have a deterministic "last use" within the local scope, pote=
ntially with restrictions on storing references to avoid incorrect usage. A=
dmittedly this option would be less analogous to register allocation.</span=
></div><span class=3D""><div>=C2=A0</div><blockquote class=3D"gmail_quote" =
style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><di=
v dir=3D"ltr"><div></div></div><div dir=3D"ltr"><blockquote class=3D"gmail_=
quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddi=
ng-left:1ex"><div dir=3D"ltr"><div dir=3D"ltr"><div><div class=3D"gmail_quo=
te"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-lef=
t:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><span><block=
quote 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>So I want to make i=
t clear to the compiler that I'd like it to be destroyed eagerly, and n=
ot just for this one but for every instance. It's a property of the cla=
ss itself that I want it's destructor to be called eagerly. If I don=
9;t want that behavior I can simply use an equivalent class without eager d=
estructor.</div></div></blockquote></span><div><br>You've provided a ve=
ry good reason not to do this at all. We do not want to encourage the proli=
feration of types that differ <i>only</i> by the presence or absence of &qu=
ot;eager destruction". We don't want `eager_unique_ptr` or `eager_=
ifstream` or `eager_vector` or whatever.<br></div></div></blockquote><div><=
br></div><div>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 <a href=
=3D"https://groups.google.com/a/isocpp.org/forum/#!msg/std-proposals/IUxA4c=
x8yHc/yKNqKl8hDgAJ" rel=3D"nofollow" target=3D"_blank">my examples</a>. The=
framework they're part of is responsible of making sure they're se=
lf-contained objects and under normal circumstances can't be used incor=
rectly.</div></div></div></div></div></blockquote></div><div dir=3D"ltr"><d=
iv><br>Your interface cannot stop people from using the object "incorr=
ectly". Consider the template example I used elsewhere:</div></div><di=
v dir=3D"ltr"><div><br><br><div style=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:#000">T t </span><span style=
=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">auto</span><span style=3D"color:#000"> tpl </span><span style=
=3D"color:#660">=3D</span><span style=3D"color:#000"> forward_as_tuple</spa=
n><span style=3D"color:#660">(</span><span style=3D"color:#000">t</span><sp=
an style=3D"color:#660">);</span><span style=3D"color:#000"><br></span><spa=
n style=3D"color:#800">//do something with tpl.</span><span style=3D"color:=
#000"><br></span></div></code></div><br></div></div><div dir=3D"ltr"><div>T=
his is perfectly valid and reasonable code; there is no reason to consider =
this code to not be "under normal circumstances" for C++. Templat=
e code like this already exists, and it will work with any type `T` which c=
an be constructed.<br><br>There is nothing you as the creator of the type `=
T` to make it so that `T`'s interface will <i>prevent</i> someone from =
doing this.<br></div></div></blockquote><div><br></div></span><div>First of=
all, there's no law that dictates that legacy code under new condition=
s still has to have the same semantics. Something as simple as <font face=
=3D"monospace">a +=C2=A0b</font> would for a C developer be nothing other t=
han an addition of scalars, while in C++ it can mean absolutely anything du=
e to operator overloading. That can be badly abused, but it can also be a v=
ery powerful abstraction. So I don't think not breaking your template e=
xample is a strict necessity.</div><div><br></div><div>Secondly, we could e=
xplore whether we can make it a compilation error to use this code with an =
eagerly destructed type/variable.</div><span class=3D""><div>=C2=A0</div><b=
lockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px =
#ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>And there are no tricks =
the compiler can play to be absolutely certain that `tpl` doesn't conta=
in 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 <i>general</i> case. To the compiler, a non-inline func=
tion is a complete black box; it knows the inputs and it knows the outputs.=
But it doesn't know what happens in the middle.<br><br>This problem is=
fundamentally identical to the temporary lifetime extension problem. Namel=
y, that this works:<br><br><div style=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:#008">const</span><span style=
=3D"color:#000"> </span><span style=3D"color:#008">auto</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">&</span><span style=
=3D"color:#000">str </span><span style=3D"color:#660">=3D</span><span style=
=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span style=
=3D"color:#008">string</span><span style=3D"color:#660">(...);</span><span =
style=3D"color:#000"><br></span><span style=3D"color:#800">//use str</span>=
<span style=3D"color:#000"><br></span></div></code></div><br>While this doe=
s not:<br><br><div style=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:#008">const</span><span style=3D"color:#000=
"> </span><span style=3D"color:#008">auto</span><span style=3D"color:#000">=
</span><span style=3D"color:#660">&</span><span style=3D"color:#000">s=
tr </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> =
std</span><span style=3D"color:#660">::</span><span style=3D"color:#008">st=
ring</span><span style=3D"color:#660">(...).</span><span style=3D"color:#00=
0">c_str</span><span style=3D"color:#660">();</span><span style=3D"color:#0=
00"><br></span><span style=3D"color:#800">//use str</span><span style=3D"co=
lor:#000"><br></span></div></code></div><br>Why doesn't this work? Beca=
use the compiler <i>cannot know</i> that `c_str` returns a pointer/referenc=
e 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 o=
f the temporary.<br><br>Your problem is the exact same thing, just for name=
d variables instead of temporaries. The compiler does not and <i>cannot</i>=
know, in all cases, whether a return value of a function contains a pointe=
r/reference to an argument or an element of an argument.<br></div></div></b=
lockquote><div><br></div></span><div>I beg to differ. Compilers can know th=
e dependency caused by this reference, through static analysis. And they ca=
n be conservative about it if insufficient information is not available. C+=
+ just chose not to support temporary lifetime extension. But we shouldn=
9;t have to restrict ourselves to such an aggressive approach for future fe=
atures. Eager destruction can either also be aggressive and not support the=
use of any references after the last local use (without or without compile=
r warning/error), or we can make it conservative and merely a hint so that =
it's up to the compiler implementation how eagerly the destructor gets =
called.</div><span class=3D""><div>=C2=A0</div><blockquote class=3D"gmail_q=
uote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1e=
x"><div dir=3D"ltr"><div>Your framework cannot prevent "incorrect"=
; use of the type. So your proposal is flawed.<br></div></div></blockquote>=
<div><br></div></span><div>Many C++ features can be used incorrectly with n=
othing to prevent you from it. That hasn't stopped them from making it =
into the standard. That said, if this is really a major concern of eager de=
struction, then we should explore how we can make some or all of the incorr=
ect uses a compiler error, or, it means we have to go with the conservative=
option.=C2=A0</div></div></div><span class=3D"">
<p></p>
-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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" target=3D"_=
blank">std-proposals+unsubscribe@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></span>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAE7XuEU1qjr6dLqzKUyAQSGVLuCwFMykr4G_=
6GFP77AGEwL-xQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
target=3D"_blank">https://groups.google.com/a/<wbr>isocpp.org/d/msgid/std-=
<wbr>proposals/<wbr>CAE7XuEU1qjr6dLqzKUyAQSGVLuCwF<wbr>Mykr4G_6GFP77AGEwL-x=
Q%40mail.<wbr>gmail.com</a>.<br>
</blockquote></div><br></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/CAKiZDp2mOy1cYfHys4A%3D5GfR0-1bidoKhe=
yOo2oWVCXEw_RteQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAKiZDp2mOy1cYf=
Hys4A%3D5GfR0-1bidoKheyOo2oWVCXEw_RteQ%40mail.gmail.com</a>.<br />
--94eb2c12474ed3963d053b5386e9--
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Wed, 31 Aug 2016 11:05:45 -0400
Raw View
On 2016-08-29 16:38, Nicol Bolas wrote:
> On Monday, August 29, 2016 at 3:05:59 PM UTC-4, Matthew Woehlke wrote:
>> On 2016-08-29 14:46, Nicol Bolas wrote:
>>> 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
>>
>> I think having explicit temporary types might help here:
>>
>> std::string::c_str() -> char const* register; // declaration
>>
>> // error: taking reference of register-qualified type.
>> const auto &str = std::string(...).c_str();
>>
>> Obviously, it is too late to change std::string this way, but it would
>> help us write better API's going forward.
>
> How would that solve the problem? How does the compiler connect the return
> value's lifetime to the lifetime of one of the function parameters?* Which*
> parameter should it connect it to? All of them?
....yes? I'm not sure you're asking the right question; `register` here
means that the value becomes invalid "almost immediately", i.e. as soon
as the inputs that led to its "creation" change, the return value is
invalidated. (So, yes, I want to say "all of them" is the correct answer.)
> And why would you use `register` of all things for that?
It grew out of the original idea of `register` being used to annotate
something that is "more ephemeral than usual". (And also, because it's
available.) Nothing says we couldn't use something else.
> P0066 provided a more comprehensive solution to lifetime analysis. And it
> was ultimately rejected
> <https://botondballo.wordpress.com/2015/11/09/trip-report-c-standards-meeting-in-kona-october-2015/>
> .
Ah, well, that's not reassuring. Oh, well. I'm not sure I agree that the
problem is 'too niche', but...
--
Matthew
--
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/57C6F249.1030601%40gmail.com.
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 31 Aug 2016 10:45:31 -0700 (PDT)
Raw View
------=_Part_624_617248602.1472665531944
Content-Type: multipart/alternative;
boundary="----=_Part_625_321781226.1472665531945"
------=_Part_625_321781226.1472665531945
Content-Type: text/plain; charset=UTF-8
On Tuesday, August 30, 2016 at 11:20:54 AM UTC-4, Nicolas Capens wrote:
>
> On Mon, Aug 29, 2016 at 2:46 PM Nicol Bolas <jmck...@gmail.com
> <javascript:>> wrote:
>
With that out of the way, note that it's only one of the two options.
> Either we use eager destruction as a hint, so it does become an
> implementation detail. You seem to be liking
> <https://groups.google.com/a/isocpp.org/d/msg/std-proposals/IUxA4cx8yHc/Q2kIq3lHEQAJ>
> that idea. But that goes against your "the point in time when an
> automatic variable is destroyed should not be a *mystery*" mantra.
>
There's a difference between "liking" an idea and "thinking that it isn't
flawed". My feelings on the attribute approach are the latter. That is, if
a feature like this is to happen, one that causes the early destruction of
an object based on the last use of its name, without care to the existence
of references and the like, then annotation at the point of definition for
that object is the approach that avoids flaws the most. It's the approach
which breaks no existing code, provides the desired functionality, and
makes sure that the responsibilities *required* by the optimization are
shouldered by the people who actually *want it*.
That doesn't mean I *like* the idea. Personally, I think broad use of this
feature, *in any form*, will lead to code that is needlessly difficult to
reason about. I think it would be better for people who have a genuine need
to clean up objects early to simply *clean up objects early* via existing
tools (or destructive move, should that ever show up). This way, compilers
don't have to implement name-usage-analysis through complex branching code
to figure out when you "last used" a name. Because destruction is done
explicitly, it makes your code easier to reason about on inspection, since
everyone can clearly see exactly when an object has been destroyed (code is
read more often than it is written).
The localized attribute form is merely the least bad of the alternatives.
Don't mistake that for me thinking that it's a good idea.
> 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.
>>
>
> First of all, there's no law that dictates that legacy code under new
> conditions still has to have the same semantics. Something as simple as a
> + b would for a C developer be nothing other than an addition of scalars,
> while in C++ it can mean absolutely anything due to operator overloading.
> That can be badly abused, but it can also be a very powerful abstraction.
> So I don't think not breaking your template example is a strict necessity.
>
Operator overloading works by taking syntax that would have been illegal
and making it legal. Without operator overloading, applying + to class
types would be a syntax error.
So you're making a false equivalence here. Your feature is exactly the
opposite of operator overloading. OO takes illegal syntax and makes it
potentially legal, while yours takes meaningful, functioning syntax and
makes it potentially illegal.
*Silently* illegal.
We don't add features to C++ that break existing code like this:
transparently and silently. We can do that, but only if the benefits of the
feature outweigh the downsides. I fail to see how the benefits of putting
the declaration in the type outweigh the downsides here.
Secondly, we could explore whether we can make it a compilation error to
> use this code with an eagerly destructed type/variable.
>
I'm curious as to exactly how that would work. There are infinitely many
permutations of this code. The only commonalities between them are:
1: The creation of an object of that type on the stack.
2: The passing of a pointer/reference of that type to a function that
returns a value.
3: The returned value happening to include a pointer/reference to that
object or some object that it controls.
It is impossible to know that #3 happens, given just a function
declaration. And when dealing with any dynamic code (virtual functions,
function pointers, `any`, `function`, DLL boundaries, etc), a function
declaration is all you have. So how would you presume to error on trying to
compile this?
You can't eliminate #2; calling a member function passes a pointer to that
object to the member function. You can't even play games about there being
a pointer/reference in the return value of the object's type, since it's
possible to fake that in ways compilers cannot detect. See the tuple
example, where if the implementation uses fake-subobjects, the compiler
can't tell that the tuple contains a reference.
So you can't detect #3 and you can't eliminate #2. How exactly would you
make this situation a compile error?
Your framework cannot prevent "incorrect" use of the type. So your proposal
>> is flawed.
>>
>
> Many C++ features can be used incorrectly with nothing to prevent you from
> it. That hasn't stopped them from making it into the standard.
>
Sure. But nobody would claim that C++'s temporary lifetime extension rules
aren't *flawed*.
It's one thing to have something already in the standard, then realizing
that it has significant flaws that are difficult to correct. It's quite
another to put something into the standard when you *know* it is a flawed
idea.
--
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/63938f2e-d390-4a2f-8a58-18ceff110433%40isocpp.org.
------=_Part_625_321781226.1472665531945
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, August 30, 2016 at 11:20:54 AM UTC-4, Nicolas =
Capens wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">=
<div><div dir=3D"ltr">On Mon, Aug 29, 2016 at 2:46 PM Nicol Bolas <<a hr=
ef=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"zAFfh88aEgAJ"=
rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:';return t=
rue;" onclick=3D"this.href=3D'javascript:';return true;">jmck...@gm=
ail.com</a>> wrote:<br></div></div></div></blockquote><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;"><div dir=3D"ltr"><div class=3D"gmail_quote"><di=
v></div><div>With that out of the way, note that it's only one of the t=
wo options. Either we use eager destruction as a hint, so it does become an=
implementation detail. You seem to be <a href=3D"https://groups.google.com=
/a/isocpp.org/d/msg/std-proposals/IUxA4cx8yHc/Q2kIq3lHEQAJ" target=3D"_blan=
k" rel=3D"nofollow" onmousedown=3D"this.href=3D'https://groups.google.c=
om/a/isocpp.org/d/msg/std-proposals/IUxA4cx8yHc/Q2kIq3lHEQAJ';return tr=
ue;" onclick=3D"this.href=3D'https://groups.google.com/a/isocpp.org/d/m=
sg/std-proposals/IUxA4cx8yHc/Q2kIq3lHEQAJ';return true;">liking</a> tha=
t idea. But that goes against your "t<span style=3D"line-height:1.5">h=
e point in time when an automatic variable is destroyed should not be a</sp=
an><span style=3D"line-height:1.5">=C2=A0</span><i style=3D"line-height:1.5=
">mystery</i><span style=3D"line-height:1.5">" mantra. </span></div></=
div></div></blockquote><div><br>There's a difference between "liki=
ng" an idea and "thinking that it isn't flawed". My feel=
ings on the attribute approach are the latter. That is, if a feature like t=
his is to happen, one that causes the early destruction of an object based =
on the last use of its name, without care to the existence of references an=
d the like, then annotation at the point of definition for that object is t=
he approach that avoids flaws the most. It's the approach which breaks =
no existing code, provides the desired functionality, and makes sure that t=
he responsibilities <i>required</i> by the optimization are shouldered by t=
he people who actually <i>want it</i>.<br><br>That doesn't mean I <i>li=
ke</i> the idea. Personally, I think broad use of this feature, <i>in any f=
orm</i>, will lead to code that is needlessly difficult to reason about. I =
think it would be better for people who have a genuine need to clean up obj=
ects early to simply <i>clean up objects early</i> via existing tools (or d=
estructive move, should that ever show up). This way, compilers don't h=
ave to implement name-usage-analysis through complex branching code to figu=
re out when you "last used" a name. Because destruction is done e=
xplicitly, it makes your code easier to reason about on inspection, since e=
veryone can clearly see exactly when an object has been destroyed (code is =
read more often than it is written).<br><br>The localized attribute form is=
merely the least bad of the alternatives. Don't mistake that for me th=
inking that it's a good idea.<br>=C2=A0</div><blockquote class=3D"gmail=
_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;p=
adding-left: 1ex;"><div dir=3D"ltr"><div class=3D"gmail_quote"><blockquote =
class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid=
;padding-left:1ex"><div dir=3D"ltr"><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 dir=3D"ltr"><div><div class=3D"gmail_quote"><div></d=
iv><div>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 <a href=3D"http=
s://groups.google.com/a/isocpp.org/forum/#!msg/std-proposals/IUxA4cx8yHc/yK=
NqKl8hDgAJ" rel=3D"nofollow" target=3D"_blank" onmousedown=3D"this.href=3D&=
#39;https://groups.google.com/a/isocpp.org/forum/#!msg/std-proposals/IUxA4c=
x8yHc/yKNqKl8hDgAJ';return true;" onclick=3D"this.href=3D'https://g=
roups.google.com/a/isocpp.org/forum/#!msg/std-proposals/IUxA4cx8yHc/yKNqKl8=
hDgAJ';return true;">my examples</a>. 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.</div></div></div></div=
></div></blockquote></div><div dir=3D"ltr"><div><br>Your interface cannot s=
top people from using the object "incorrectly". Consider the temp=
late example I used elsewhere:</div></div><div dir=3D"ltr"><div><br><br><di=
v style=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:#000">T t </span><span style=3D"color:#660">=3D</span><span =
style=3D"color:#000"> </span><span style=3D"color:#660">...</span><span sty=
le=3D"color:#000"><br></span><span style=3D"color:#008">auto</span><span st=
yle=3D"color:#000"> tpl </span><span style=3D"color:#660">=3D</span><span s=
tyle=3D"color:#000"> forward_as_tuple</span><span style=3D"color:#660">(</s=
pan><span style=3D"color:#000">t</span><span style=3D"color:#660">);</span>=
<span style=3D"color:#000"><br></span><span style=3D"color:#800">//do somet=
hing with tpl.</span><span style=3D"color:#000"><br></span></div></code></d=
iv><br></div></div><div dir=3D"ltr"><div>This is perfectly valid and reason=
able code; there is no reason to consider this code to not be "under n=
ormal circumstances" for C++. Template code like this already exists, =
and it will work with any type `T` which can be constructed.<br><br>There i=
s nothing you as the creator of the type `T` to make it so that `T`'s i=
nterface will <i>prevent</i> someone from doing this.<br></div></div></bloc=
kquote><div><br></div><div>First of all, there's no law that dictates t=
hat legacy code under new conditions still has to have the same semantics. =
Something as simple as <font face=3D"monospace">a +=C2=A0b</font> would for=
a C developer be nothing other than an addition of scalars, while in C++ i=
t can mean absolutely anything due to operator overloading. That can be bad=
ly abused, but it can also be a very powerful abstraction. So I don't t=
hink not breaking your template example is a strict necessity.</div></div><=
/div></blockquote><div><br>Operator overloading works by taking syntax that=
would have been illegal and making it legal. Without operator overloading,=
applying + to class types would be a syntax error.<br><br>So you're ma=
king a false equivalence here. Your feature is exactly the opposite of oper=
ator overloading. OO takes illegal syntax and makes it potentially legal, w=
hile yours takes meaningful, functioning syntax and makes it potentially il=
legal.<br><br><i>Silently</i> illegal.<br><br>We don't add features to =
C++ that break existing code like this: transparently and silently. We can =
do that, but only if the benefits of the feature outweigh the downsides. I =
fail to see how the benefits of putting the declaration in the type outweig=
h the downsides here.<br><br></div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div dir=3D"ltr"><div class=3D"gmail_quote"><div></div><div>Secondly,=
we could explore whether we can make it a compilation error to use this co=
de with an eagerly destructed type/variable.</div></div></div></blockquote>=
<div><br>I'm curious as to exactly how that would work. There are infin=
itely many permutations of this code. The only commonalities between them a=
re:<br><br>1: The creation of an object of that type on the stack.<br><br>2=
: The passing of a pointer/reference of that type to a function that return=
s a value.<br><br>3: The returned value happening to include a pointer/refe=
rence to that object or some object that it controls.<br><br>It is impossib=
le to know that #3 happens, given just a function declaration. And when dea=
ling with any dynamic code (virtual functions, function pointers, `any`, `f=
unction`, DLL boundaries, etc), a function declaration is all you have. So =
how would you presume to error on trying to compile this?<br><br>You can=
9;t eliminate #2; calling a member function passes a pointer to that object=
to the member function. You can't even play games about there being a =
pointer/reference in the return value of the object's type, since it=
9;s possible to fake that in ways compilers cannot detect. See the tuple ex=
ample, where if the implementation uses fake-subobjects, the compiler can&#=
39;t tell that the tuple contains a reference.<br><br>So you can't dete=
ct #3 and you can't eliminate #2. How exactly would you make this situa=
tion a compile error?<br><br></div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div dir=3D"ltr"><div><div> </div></div></div></blockquote><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></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>Your fr=
amework cannot prevent "incorrect" use of the type. So your propo=
sal is flawed.<br></div></div></blockquote><div><br></div><div>Many C++ fea=
tures can be used incorrectly with nothing to prevent you from it. That has=
n't stopped them from making it into the standard.</div></div></div></b=
lockquote><div><br>Sure. But nobody would claim that C++'s temporary li=
fetime extension rules aren't <i>flawed</i>.<br><br>It's one thing =
to have something already in the standard, then realizing that it has signi=
ficant flaws that are difficult to correct. It's quite another to put s=
omething into the standard when you <i>know</i> it is a flawed idea.</div><=
/div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/63938f2e-d390-4a2f-8a58-18ceff110433%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/63938f2e-d390-4a2f-8a58-18ceff110433=
%40isocpp.org</a>.<br />
------=_Part_625_321781226.1472665531945--
------=_Part_624_617248602.1472665531944--
.