Prev: reasoning of ::std::cout (ostream) conversion w.r.t. plain, signed and unsigned chars...
Next: reasoning of ::std::cout (ostream) conversion w.r.t. plain, signed and unsigned chars...
From: viboes on 12 Jan 2010 01:35 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 14 Jan 2010 02:08
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! ] |