From: viboes on
On Jan 12, 1:17 am, DeMarcus <use_my_alias_h...(a)hotmail.com> wrote:
> > I also think that it's beneficial to have
> > scope guard close to the "guarded" code, for the purpose of having
> > these related things close by.
>
> It just hit me that ScopeGuards may be exception-unsafe!
> Look at this code.
>
> exampleVector_.push_back( "Something" );
> ScopeGuard guard1 = makeScopeGuard( exampleVector_,
> &std::vector<std::string>::pop_back );
>
> What if makeScopeGuard throws?! It won't in this particular example, but
> if the function to makeScopeGuard is a functor or if it takes
> parameters, any of these may throw when copied. Then we have done an
> irreversible push_back.
>
> Mustn't we reverse the order to the following?
>
> ScopeGuard guard1 = makeScopeGuard( exampleVector_,
> &std::vector<std::string>::pop_back );
> exampleVector_.push_back( "Something" );
>
> If so, then it's also wrong in the original article by Alexandrescu &
> Marginean.http://www.ddj.com/cpp/184403758
>
> Or am I thinking wrong?


Hi,

I don't know if makeScopeGuard can throw but in any case it must not
throw. If you give a functor you need to ensure that the copy
construction don't throw. Otherwise you will enter on a loop. I don't
remember if ScopeGuard or ScopedExit use move semantics, but this
should help to avoid unneeded exceptions as no copy is needed.

Vicente


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Ulrich Eckhardt on
DeMarcus wrote:
> Look at this code.
>
> exampleVector_.push_back( "Something" );
> ScopeGuard guard1 = makeScopeGuard( exampleVector_,
> &std::vector<std::string>::pop_back );
>
> What if makeScopeGuard throws?! It won't in this particular example, but
> if the function to makeScopeGuard is a functor or if it takes
> parameters, any of these may throw when copied. Then we have done an
> irreversible push_back.

The parameters passed to makeScopeGuard() must be passed by reference, so
that this can not throw. Their use must not require any additional
resources (otherwise you would end up with a destructor that throws). If
storing them (which involves copying) throws, it must invoke the cleanup
immediately, so there you will actually need a try/catch-clause.

> Mustn't we reverse the order to the following?
>
> ScopeGuard guard1 = makeScopeGuard( exampleVector_,
> &std::vector<std::string>::pop_back );
> exampleVector_.push_back( "Something" );

Okay, what if push_back() throws now? Then the scope guard would pop a
nonexisting element off the vector.

Uli

--
Sator Laser GmbH
Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]