220 12601 <25b42b7b-dde3-4b23-a387-f8aa4788b887@isocpp.org> article
Path: news.gmane.org!not-for-mail
From: Andrew Sandoval <sandoval@netwaysglobal.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Questions about N3949 - Scoped Resource - Generic
 RAII Wrapper for the Standard Library
Date: Sun, 31 Aug 2014 12:21:44 -0700 (PDT)
Lines: 298
Approved: news@gmane.org
Message-ID: <25b42b7b-dde3-4b23-a387-f8aa4788b887@isocpp.org>
References: <038222e0-66c3-4837-b158-e911dffb3c55@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0
Content-Type: multipart/alternative; 
	boundary="----=_Part_1_890328641.1409512904326"
X-Trace: ger.gmane.org 1409512913 13615 80.91.229.3 (31 Aug 2014 19:21:53 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Sun, 31 Aug 2014 19:21:53 +0000 (UTC)
To: std-proposals@isocpp.org
Original-X-From: std-proposals+bncBDIZ5RW5Y4IBBSPLRWQAKGQEH3L7DII@isocpp.org Sun Aug 31 21:21:48 2014
Return-path: <std-proposals+bncBDIZ5RW5Y4IBBSPLRWQAKGQEH3L7DII@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-oa0-f69.google.com ([209.85.219.69])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBDIZ5RW5Y4IBBSPLRWQAKGQEH3L7DII@isocpp.org>)
	id 1XOAhA-0001fO-4Q
	for gclcip-std-proposals@m.gmane.org; Sun, 31 Aug 2014 21:21:48 +0200
Original-Received: by mail-oa0-f69.google.com with SMTP id i7sf28145452oag.0
        for <gclcip-std-proposals@m.gmane.org>; Sun, 31 Aug 2014 12:21:47 -0700 (PDT)
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:date:from:to:message-id:in-reply-to:references
         :subject:mime-version:x-original-sender:reply-to:precedence
         :mailing-list:list-id:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe:content-type;
        bh=egD0+YAl9bHeYoFxBJkExAi3WSJMhg8BT+189aiwXrc=;
        b=Warq3Dj1v2DIMya1UHb93g9agMnrzMJN6I781N77ScZDhySrMvMTDDFl2vJF+eNq0h
         ajquKxv5dm4ijgCC9oHQMBbhLupPXpYjAUCuVFyd/c/Lshs1e6KZbX74cGXiwuKNrtvF
         15exQ5iCMQ/wygZH7Juzqdgufoz0Bwd7IJPOcFSBO6o0eaatE1gxCYNdwKcAzgqnaDnM
         A32Kds4EihNuLFKb9dhsYkgUYai0+wNxqv9njwPh8aSDBuFQ0yRX5TJKmQE7V1/aFc1p
         aC3kAjh6XGCD4m61N0+AH5nhaaTF/E+Yd5L89x9nenffpaVPGutYLVj+Q2YgTqZONEZI
         EvxA==
X-Gm-Message-State: ALoCoQl2CGMDz8/G4K8opxqY22H/s6zCyrjZzps2Z8YPAsnuxI+D31OmIZq52lh1jMol1CsIV4Rw
X-Received: by 10.182.24.8 with SMTP id q8mr13384852obf.25.1409512907002;
        Sun, 31 Aug 2014 12:21:47 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.182.78.103 with SMTP id a7ls614616obx.92.gmail; Sun, 31 Aug
 2014 12:21:45 -0700 (PDT)
X-Received: by 10.182.73.135 with SMTP id l7mr27826obv.15.1409512905527;
        Sun, 31 Aug 2014 12:21:45 -0700 (PDT)
In-Reply-To: <038222e0-66c3-4837-b158-e911dffb3c55@isocpp.org>
X-Original-Sender: sandoval@netwaysglobal.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Google-Group-Id: 399137483710
List-Post: <http://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <http://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <http://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>,
 <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:12601
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/12601>

------=_Part_1_890328641.1409512904326
Content-Type: text/plain; charset=UTF-8

On Sunday, August 31, 2014 9:03:18 AM UTC-5, Adi Shavit wrote:
>
> Hi,
>
>   It is often useful to have resources as members of a class to be cleaned 
> upon destruction (this is what RAII is all about!).
> However, to declare a member of scoped_resource in the class header, I 
> would need to know the type of the deleter (as opposed to, e.g. shared_ptr 
> which does not require this).
> 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.
>
> All the examples I saw use 'auto' for local scope, but AFAIK, you cannot 
> use auto in the class declaration since the size needs to be known at 
> compile time.
> Am I missing something here or is this by design?
> What is the rational for this and how would one a succinct scoped_resource 
> declaration?
>
> Warm regards,
> Adi
>

Adi,

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.  It's not great 
syntactically, but here is an example:

#include "stdafx.h"
#include "N3949/unique_resource"
#include <windows.h>
#include <string>

class A
{
private:
    std::experimental::unique_resource_t<HANDLE, decltype(&CloseHandle)> 
m_hFile;
    A() = delete;
public:
    A(const std::wstring &wstrFile) : 
        m_hFile(CreateFile(wstrFile.c_str(), GENERIC_READ, FILE_SHARE_READ, 
nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr), &CloseHandle)
    {
    }
};

int main(int argc, const char* argv[])
{
    A a(L"test.txt");
    return 0;
}



As previously mentioned, the problem with the example is that you have to 
really ugly it up to test the return value of CreateFile in order to pass a 
true/false properly as the last parameter to unique_resource_t's 
constructor.  If we have auto class members then obviously it is much 
easier and cleaner as you can use unique_resource to generate a 
unique_resource_t.

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 hope that is helpful.

-Andrew Sandoval

-- 

--- 
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_1_890328641.1409512904326
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Sunday, August 31, 2014 9:03:18 AM UTC-5, Adi Shavit 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">Hi,<div><=
br></div><div>&nbsp; It is often useful to have resources as members of a c=
lass to be cleaned upon destruction (this is what RAII is all about!).</div=
><div>However, to declare a member of scoped_resource in the class header, =
I would need to know the type of the deleter (as opposed to, e.g. shared_pt=
r which does not require this).</div><div>I guess I could use decltype in t=
he member type definition, but that would require stating the actual delete=
r at 2 different places: header + the initialization.</div><div><br></div><=
div>All the examples I saw use 'auto' for local scope, but AFAIK, you canno=
t use auto in the class declaration since the size needs to be known at com=
pile time.</div><div>Am I missing something here or is this by design?</div=
><div>What is the rational for this and how would one a succinct scoped_res=
ource declaration?</div><div><br></div><div>Warm regards,</div><div>Adi</di=
v></div></blockquote><div><br>Adi,<br><br>Unfortunately there is not a real=
ly good way to handle this with N3949.&nbsp; The original proposal N3677 ha=
d a class called scoped_resource and examples of how it could be used as a =
class member.&nbsp; And because the delete time check was in the object's d=
estructor instead of being a constructor argument, the no-delete value wasn=
't checked until just before the delete function would've been called (unli=
ke N3949.)<br><br>Nevertheless, you can still do something similar.&nbsp; I=
t's not great syntactically, but here is an example:<br><br><div class=3D"p=
rettyprint" 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;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span styl=
e=3D"color: #800;" class=3D"styled-by-prettify">#include</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #080;" class=3D"styled-by-prettify">"stdafx.h"</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #800=
;" class=3D"styled-by-prettify">#include</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> </span><span style=3D"color: #080;" class=3D=
"styled-by-prettify">"N3949/unique_resource"</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #800;" c=
lass=3D"styled-by-prettify">#include</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #080;" class=3D"sty=
led-by-prettify">&lt;windows.h&gt;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: #800;" class=3D"st=
yled-by-prettify">#include</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><span style=3D"color: #080;" class=3D"styled-by-pre=
ttify">&lt;string&gt;</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br><br></span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">class</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> A<br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">private</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">:</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; std</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">experimental</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">unique_resource_t</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">HANDLE</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: #008;" cla=
ss=3D"styled-by-prettify">decltype</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(&amp;</span><span style=3D"color: #606;" class=3D"=
styled-by-prettify">CloseHandle</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">)&gt;</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> m_hFile</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br>&nbsp; &nbsp; A</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">()</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">delete</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">public</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">:</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>&nbsp; &nbsp; A</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">(</span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">const</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> std</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">wstring </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">&amp;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">ws=
trFile</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</s=
pan><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>&nbsp; &nbsp; &nbsp; &nbsp=
; m_hFile</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(=
</span><span style=3D"color: #606;" class=3D"styled-by-prettify">CreateFile=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify">wstrFile</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">.</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">c_str</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">(),</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> GENERIC_READ</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> FILE_SHARE_READ</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">nullptr</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> OPEN_EXISTING</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 FILE_ATTRIBUTE_NORMAL</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">nullpt=
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 sty=
le=3D"color: #660;" class=3D"styled-by-prettify">&amp;</span><span style=3D=
"color: #606;" class=3D"styled-by-prettify">CloseHandle</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; </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"styled-by-prettify">};</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br><br></span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> main</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">(</span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">int</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> arg=
c</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">const</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">char</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">*</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> argv</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">[])</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbs=
p; &nbsp; A a</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">L</spa=
n><span style=3D"color: #080;" class=3D"styled-by-prettify">"test.txt"</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; </spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">return</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #066;" class=3D"styled-by-prettify">0</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"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br><br></span></div></code></div><br><br>As previously ment=
ioned, the problem with the example is that you have to really ugly it up t=
o test the return value of CreateFile in order to pass a true/false properl=
y as the last parameter to unique_resource_t's constructor.&nbsp; If we hav=
e auto class members then obviously it is much easier and cleaner as you ca=
n use unique_resource to generate a unique_resource_t.<br><br>Take a look a=
t the examples in N3677 (<a href=3D"http://www.andrewlsandoval.com/scope_ex=
it/">http://www.andrewlsandoval.com/scope_exit/</a>) and N3830 (<a href=3D"=
http://www.andrewlsandoval.com/scoped_resource/N3830_scoped_resource.pdf">h=
ttp://www.andrewlsandoval.com/scoped_resource/N3830_scoped_resource.pdf</a>=
) for more history and details.&nbsp; Ultimately the Library Evolution Work=
ing Group preferred the classes in N3949.&nbsp; Personally I would much rat=
her have N3949's classes in the standard library than not have anything!&nb=
sp; 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 cl=
ass to encapsulate, and that has resulted in a lot of code that leaks in ge=
neral, and even worse, leaks on unwind.&nbsp; (Worse because fewer develope=
rs are cognizant of the risk of leaking on unwind.)<br><br>I strongly belie=
ve that by binding the clean-up to the initialization, visibly and upfront,=
 you cause the developer to think more carefully about resource lifetime, r=
esulting in better code.&nbsp;&nbsp; And, whether the old school method is =
to create small objects that simply encapsulate and clean-up (such as a Fil=
e object with constructor opening a file, and the destructor closing it), o=
r if it is the manual C-style method, both tend to separate and in some cas=
es substantially distance initialization from clean-up and therefore don't =
force the developer to think about resource lifetime up front.&nbsp; And wh=
ile it is obvious that this can work, it can also increase the hard to catc=
h bugs, especially in the latter case.<br><br>I hope that is helpful.<br><b=
r>-Andrew Sandoval<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&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
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_1_890328641.1409512904326--

.
