Boost logo

Boost :

Subject: Re: [boost] Proposed new RAII Library
From: Sergey Cheban (s.cheban_at_[hidden])
Date: 2012-09-15 05:11:15


15.09.2012 5:27, John Bytheway пишет:

>>> boost::scope_guard lolwhat( [&](){ CloseHandle(handle); } );
>>>
>>> ...
>>> lolwhat.dismiss();
>> What about
>> boost::exception_guard somename( [&](){ CloseHandle(handle); } );
>> that calls the function/lambda only if std::uncaught_exception() returns
>> true?
>
> std::uncaught_exception is very dangerous to use in this way. See
>
> http://www.gotw.ca/gotw/047.htm
This article is not about my idea. I do not propose to throw from the
destructor. I propose to use uncaught_exception() to determine whether
the resources must be freed on the scope exit or not.

I propose to use the following

{
   HANDLE h = CheckHandle( CreateFile(...) ); //CheckHandle() may throw
   boost::exception_guard guard( [&](){
     CloseHandle(h);
   } );

   //other code that can throw

   return h; //note that h must not be closed
}

instead of the following

{
   bool bDontClose = false;
   HANDLE h = CheckHandle( CreateFile(...) ); //CheckHandle() may throw
   boost::scope_guard guard( [&](){
     if( !bDontClose )
       CloseHandle(h);
   } );

   //other code that can throw

   bDontClose = true;
   return h; //note that h must not be closed
}

> In short: your function will misbehave if called from a destructor
> during stack unwinding.
It seems strange to me. Destructors are the only places where
uncaught_exception() may return true, right? What's wrong with the
following?

~exception_guard()
{
   if( uncaught_exception() )
     f();
}

Is it less safe than the following?

~scope_guard()
{
   f();
}

--
Best regards,
Sergey Cheban

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk