Topic: Questions about N3949 - Scoped Resource -
Author: Adi Shavit <adishavit@gmail.com>
Date: Mon, 1 Sep 2014 08:48:20 +0300
Raw View
--047d7b6225aca70fc00501fa8ed0
Content-Type: text/plain; charset=UTF-8
Hi Andrew,
I guess I could use decltype in the member type definition, but that would
>> require stating the actual deleter at 2 different places: header + the
>> initialization.
>>
>
> Unfortunately there is not a really good way to handle this with N3949.
> The original proposal N3677 had a class called scoped_resource and examples
> of how it could be used as a class member. And because the delete time
> check was in the object's destructor instead of being a constructor
> argument, the no-delete value wasn't checked until just before the delete
> function would've been called (unlike N3949.)
>
> Nevertheless, you can still do something similar. <snip>
>
Yes, That example is just what I had in mind.
Note that as I wrote, you had to use decltype(&CloseHandle) at the member
type declaration and refer to CloseHandle again on construction.
I guess this is the heart of the question: why not have the deleter
accepted only on construction, and not be part of the type - as in
shared_ptr<> ?
I wasn't really referring to the checked version and the last parameter
issue.
Take a look at the examples in N3677 (
> http://www.andrewlsandoval.com/scope_exit/) and N3830 (
> http://www.andrewlsandoval.com/scoped_resource/N3830_scoped_resource.pdf)
> for more history and details. Ultimately the Library Evolution Working
> Group preferred the classes in N3949. Personally I would much rather have
> N3949's classes in the standard library than not have anything! The "old
> school" way that David mentioned may be different than what I have in mind,
> but from my experience the old school way was to not use a class to
> encapsulate, and that has resulted in a lot of code that leaks in general,
> and even worse, leaks on unwind. (Worse because fewer developers are
> cognizant of the risk of leaking on unwind.)
>
> I strongly believe that by binding the clean-up to the initialization,
> visibly and upfront, you cause the developer to think more carefully about
> resource lifetime, resulting in better code. And, whether the old school
> method is to create small objects that simply encapsulate and clean-up
> (such as a File object with constructor opening a file, and the destructor
> closing it), or if it is the manual C-style method, both tend to separate
> and in some cases substantially distance initialization from clean-up and
> therefore don't force the developer to think about resource lifetime up
> front. And while it is obvious that this can work, it can also increase
> the hard to catch bugs, especially in the latter case.
>
I completely agree with what you write, which is why I was excited when I
saw your proposals.
I am hoping that the solution will indeed be generic enough to allow usage
in all common cases and significantly reduce the amount of boilerplate
wrappers and indirection code that I often feel compelled to write to avoid
all the pitfalls you mention.
Adi
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--047d7b6225aca70fc00501fa8ed0
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Hi Andrew,<div><br></div><div class=3D"gmail_extra"><div c=
lass=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0px =
0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);bord=
er-left-style:solid;padding-left:1ex">
<div dir=3D"ltr"><div class=3D""><blockquote class=3D"gmail_quote" style=3D=
"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,2=
04,204);border-left-style:solid;padding-left:1ex"><div dir=3D"ltr"><div>I g=
uess I could use decltype in the member type definition, but that would req=
uire stating the actual deleter at 2 different places: header + the initial=
ization.<br>
</div></div></blockquote></div><div></div></div></blockquote><div>=C2=A0</d=
iv><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bord=
er-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:soli=
d;padding-left:1ex">
<div dir=3D"ltr"><div>Unfortunately there is not a really good way to handl=
e this with N3949.=C2=A0 The original proposal N3677 had a class called sco=
ped_resource and examples of how it could be used as a class member.=C2=A0 =
And because the delete time check was in the object's destructor instea=
d of being a constructor argument, the no-delete value wasn't checked u=
ntil just before the delete function would've been called (unlike N3949=
..)<br>
<br>Nevertheless, you can still do something similar. <snip><br></div=
></div></blockquote><div><br></div><div>Yes, That example is just what I ha=
d in mind.=C2=A0</div><div>Note that as I wrote, you had to use=C2=A0<span =
style=3D"font-family:monospace;font-size:10px;color:rgb(0,0,136);background=
-color:rgb(250,250,250)">decltype</span><span style=3D"font-family:monospac=
e;font-size:10px;color:rgb(102,102,0);background-color:rgb(250,250,250)">(&=
amp;</span><span style=3D"font-family:monospace;font-size:10px;color:rgb(10=
2,0,102);background-color:rgb(250,250,250)">CloseHandle</span><span style=
=3D"font-family:monospace;font-size:10px;color:rgb(102,102,0);background-co=
lor:rgb(250,250,250)">)</span>=C2=A0at the member type declaration and refe=
r to=C2=A0<span style=3D"color:rgb(102,0,102);font-family:monospace;font-si=
ze:10px;background-color:rgb(250,250,250)">CloseHandle</span>=C2=A0again on=
construction.</div>
<div>I guess this is the heart of the question: why not have the deleter ac=
cepted only on construction, and not be part of the type - as in <font face=
=3D"courier new, monospace">shared_ptr<></font> ?</div><div><br></div=
>
<div>I wasn't really referring to the checked version and the last para=
meter issue.</div><div><br></div><blockquote class=3D"gmail_quote" style=3D=
"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,2=
04,204);border-left-style:solid;padding-left:1ex">
<div dir=3D"ltr"><div>Take a look at the examples in N3677 (<a href=3D"http=
://www.andrewlsandoval.com/scope_exit/" target=3D"_blank">http://www.andrew=
lsandoval.com/scope_exit/</a>) and N3830 (<a href=3D"http://www.andrewlsand=
oval.com/scoped_resource/N3830_scoped_resource.pdf" target=3D"_blank">http:=
//www.andrewlsandoval.com/scoped_resource/N3830_scoped_resource.pdf</a>) fo=
r more history and details.=C2=A0 Ultimately the Library Evolution Working =
Group preferred the classes in N3949.=C2=A0 Personally I would much rather =
have N3949's classes in the standard library than not have anything!=C2=
=A0 The "old school" way that David mentioned may be different th=
an what I have in mind, but from my experience the old school way was to no=
t use a class to encapsulate, and that has resulted in a lot of code that l=
eaks in general, and even worse, leaks on unwind.=C2=A0 (Worse because fewe=
r developers are cognizant of the risk of leaking on unwind.)<br>
<br>I strongly believe that by binding the clean-up to the initialization, =
visibly and upfront, you cause the developer to think more carefully about =
resource lifetime, resulting in better code.=C2=A0=C2=A0 And, whether the o=
ld school method is to create small objects that simply encapsulate and cle=
an-up (such as a File object with constructor opening a file, and the destr=
uctor closing it), or if it is the manual C-style method, both tend to sepa=
rate and in some cases substantially distance initialization from clean-up =
and therefore don't force the developer to think about resource lifetim=
e up front.=C2=A0 And while it is obvious that this can work, it can also i=
ncrease the hard to catch bugs, especially in the latter case.<br>
</div></div></blockquote><div><br></div><div>I completely agree with what y=
ou write, which is why I was excited when I saw your proposals.</div><div>I=
am hoping that the solution will indeed be generic enough to allow usage i=
n all common cases and significantly reduce the amount of boilerplate wrapp=
ers and indirection code that I often feel compelled to write to avoid all =
the pitfalls you mention.</div>
<div><br></div><div>Adi</div></div></div></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--047d7b6225aca70fc00501fa8ed0--
.
Author: Andrew Sandoval <sandoval@netwaysglobal.com>
Date: Wed, 3 Sep 2014 08:30:29 -0700 (PDT)
Raw View
------=_Part_213_503260013.1409758229983
Content-Type: text/plain; charset=UTF-8
Adi,
On Monday, September 1, 2014 12:48:52 AM UTC-5, Adi Shavit wrote:
>
> Hi Andrew,
>
> I guess I could use decltype in the member type definition, but that would
>>> require stating the actual deleter at 2 different places: header + the
>>> initialization.
>>>
>>
>
>> Unfortunately there is not a really good way to handle this with N3949.
>> The original proposal N3677 had a class called scoped_resource and examples
>> of how it could be used as a class member. And because the delete time
>> check was in the object's destructor instead of being a constructor
>> argument, the no-delete value wasn't checked until just before the delete
>> function would've been called (unlike N3949.)
>>
>> Nevertheless, you can still do something similar. <snip>
>>
>
> Yes, That example is just what I had in mind.
> Note that as I wrote, you had to use decltype(&CloseHandle) at the member
> type declaration and refer to CloseHandle again on construction.
> I guess this is the heart of the question: why not have the deleter
> accepted only on construction, and not be part of the type - as in
> shared_ptr<> ?
>
It's just a trade-off one way or the other. In the original
unique_resource (N3677), I derived the type of the resource from the first
parameter to the deleter function. It allowed for some flexibility in
calling convention and return type on the deleter. In N3830, Peter made it
so that you could expand that even further by having multiple parameters to
a deleter function, etc., but it also became less usable IMO for class
member variables. At least until we can have auto members, which I think
would also resolve the issue with N3949...
In N3677, unique_resource still required passing the type of the deleter
and the deleter function to the constructor but provided a macro (don't
throw things please!) to remove the redundancy at construction time. It
works very well for class member variables, but it could be easily revised
to work as you've suggested -- where the type is a template parameter and
the deleter must conform to a specific signature taking a parameter of that
type -- which is what scoped_ptr<> does IIRC.
-Andy
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_213_503260013.1409758229983
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Adi,<br><br>On Monday, September 1, 2014 12:48:52 AM UTC-5=
, Adi Shavit wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D=
"ltr">Hi Andrew,<div><br></div><div><div class=3D"gmail_quote"><blockquote =
class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1=
px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:=
1ex">
<div dir=3D"ltr"><div><blockquote class=3D"gmail_quote" style=3D"margin:0px=
0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);bor=
der-left-style:solid;padding-left:1ex"><div dir=3D"ltr"><div>I guess I coul=
d use decltype in the member type definition, but that would require statin=
g the actual deleter at 2 different places: header + the initialization.<br=
>
</div></div></blockquote></div><div></div></div></blockquote><div> </d=
iv><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bord=
er-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:soli=
d;padding-left:1ex">
<div dir=3D"ltr"><div>Unfortunately there is not a really good way to handl=
e this with N3949. The original proposal N3677 had a class called sco=
ped_resource and examples of how it could be used as a class member. =
And because the delete time check was in the object's destructor instead of=
being a constructor argument, the no-delete value wasn't checked until jus=
t before the delete function would've been called (unlike N3949.)<br>
<br>Nevertheless, you can still do something similar. <snip><br></div=
></div></blockquote><div><br></div><div>Yes, That example is just what I ha=
d in mind. </div><div>Note that as I wrote, you had to use <span =
style=3D"font-family:monospace;font-size:10px;color:rgb(0,0,136);background=
-color:rgb(250,250,250)">decltype</span><span style=3D"font-family:monospac=
e;font-size:10px;color:rgb(102,102,0);background-color:rgb(250,250,250)">(&=
amp;</span><span style=3D"font-family:monospace;font-size:10px;color:rgb(10=
2,0,102);background-color:rgb(250,250,250)">CloseHandle</span><span style=
=3D"font-family:monospace;font-size:10px;color:rgb(102,102,0);background-co=
lor:rgb(250,250,250)">)</span> at the member type declaration and refe=
r to <span style=3D"color:rgb(102,0,102);font-family:monospace;font-si=
ze:10px;background-color:rgb(250,250,250)">CloseHandle</span> again on=
construction.</div>
<div>I guess this is the heart of the question: why not have the deleter ac=
cepted only on construction, and not be part of the type - as in <font face=
=3D"courier new, monospace">shared_ptr<></font> ?</div></div></div></=
div></blockquote><div><br>It's just a trade-off one way or the other. =
In the original unique_resource (N3677), I derived the type of the resourc=
e from the first parameter to the deleter function. It allowed for so=
me flexibility in calling convention and return type on the deleter. =
In N3830, Peter made it so that you could expand that even further by havin=
g multiple parameters to a deleter function, etc., but it also became less =
usable IMO for class member variables. At least until we can have aut=
o members, which I think would also resolve the issue with N3949...<br><br>=
In N3677, unique_resource still required passing the type of the deleter an=
d the deleter function to the constructor but provided a macro (don't throw=
things please!) to remove the redundancy at construction time. It wo=
rks very well for class member variables, but it could be easily revised to=
work as you've suggested -- where the type is a template parameter and the=
deleter must conform to a specific signature taking a parameter of that ty=
pe -- which is what scoped_ptr<> does IIRC.<br><br>-Andy</div></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_213_503260013.1409758229983--
.
Author: Adi Shavit <adishavit@gmail.com>
Date: Wed, 3 Sep 2014 11:35:32 -0700 (PDT)
Raw View
------=_Part_3847_1202697029.1409769332771
Content-Type: text/plain; charset=UTF-8
Hi Andrew,
In N3677, unique_resource still required passing the type of the deleter
> and the deleter function to the constructor but provided a macro (don't
> throw things please!) to remove the redundancy at construction time. It
> works very well for class member variables, but it could be easily revised
> to work as you've suggested -- where the type is a template parameter and
> the deleter must conform to a specific signature taking a parameter of that
> type -- which is what scoped_ptr<> does IIRC.
>
I guess, using a macro at construction would remove the redundancy, but it
still keeps the deleter function separated from the initialization, which
is one of the most desirable features of this class.
I would prefer to state the deleter at the point of construction and not at
the declaration.
Another reason for the is the compilation firewall.
The resource type can usually be fwd declared without a full blown
#include, while the deleter type will usually involve a full #include
(since you would usually prefer not to write special fwd headers esp. for
3rd party libraries). Moreover, by not #including the full function
headers, your class header might be kept cross platform while the actual
deleter is initialized to platform specific functions.
Just to clarify, I am not trying to nit-pick here.
I am speaking from painful experiences of trying to C++-ify C API resource
management (within larger C++ projects), often on multiple platforms.
shared_ptr<> <http://en.cppreference.com/w/cpp/memory/shared_ptr> does not
specify the deleter type.
unique_ptr<> <http://en.cppreference.com/w/cpp/memory/unique_ptr> seems to
require it and boost::scoped_ptr<>
<http://www.boost.org/doc/libs/1_56_0/libs/smart_ptr/scoped_ptr.htm> does
not support deleters.
Since this proposal has been discussed at multiple meetings, is it not too
late to have this discussion at all?
Warm regards,
Adi
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_3847_1202697029.1409769332771
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Hi Andrew,<div><br></div><div><blockquote class=3D"gmail_q=
uote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;pad=
ding-left: 1ex;"><div dir=3D"ltr"><div>In N3677, unique_resource still requ=
ired passing the type of the deleter and the deleter function to the constr=
uctor but provided a macro (don't throw things please!) to remove the redun=
dancy at construction time. It works very well for class member varia=
bles, but it could be easily revised to work as you've suggested -- where t=
he type is a template parameter and the deleter must conform to a specific =
signature taking a parameter of that type -- which is what scoped_ptr<&g=
t; does IIRC.<br></div></div></blockquote><div> </div></div><div>I gue=
ss, using a macro at construction would remove the redundancy, but it still=
keeps the deleter function separated from the initialization, which is one=
of the most desirable features of this class. </div><div>I would pref=
er to state the deleter at the point of construction and not at the declara=
tion.</div><div>Another reason for the is the compilation firewall.</div><d=
iv>The resource type can usually be fwd declared without a full blown #incl=
ude, while the deleter type will usually involve a full #include (since you=
would usually prefer not to write special fwd headers esp. for 3rd party l=
ibraries). Moreover, by not #including the full function headers, your clas=
s header might be kept cross platform while the actual deleter is initializ=
ed to platform specific functions.</div><div><br></div><div>Just to clarify=
, I am not trying to nit-pick here. </div><div>I am speaking from pain=
ful experiences of trying to C++-ify C API resource management (within larg=
er C++ projects), often on multiple platforms.</div><div><br></div><div><a =
href=3D"http://en.cppreference.com/w/cpp/memory/shared_ptr">shared_ptr<&=
gt;</a> does not specify the deleter type. </div><div><a href=3D"http:=
//en.cppreference.com/w/cpp/memory/unique_ptr">unique_ptr<></a> =
seems to require it and <a href=3D"http://www.boost.org/doc/libs/1_56_0/lib=
s/smart_ptr/scoped_ptr.htm">boost::scoped_ptr<></a> does not support =
deleters.</div><div><br></div><div>Since this proposal has been discussed a=
t multiple meetings, is it not too late to have this discussion at all?</di=
v><div><br></div><div>Warm regards,</div><div>Adi</div><div><br></div><div>=
<br></div></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_3847_1202697029.1409769332771--
.