TITLE: bring in the cleaning lady (Newsgroups: comp.lang.c++.moderated, 10 Apr 97) SUTTER: Herb Sutter > CHALLENGE: With many current compilers, using "try" and "catch" > often adds unnecessary overhead to your programs, which would be > nice to avoid in this kind of low-level reusable container. Can > you implement all Stack member functions as required without > ever using "try" or "catch"? WADE: "Bill Wade" A pattern which often works for this problem (but I don't know if I'd say it avoids unnecessary overhead) is to transform try{ Stuff(); } catch(...){ Cleanup(args); throw; } into Cleaning lady(args); Stuff(); lady.NeverMind(); where the code for ~Cleaning() is approximately Cleaning::~Cleaning() { if(nobody_said_nevermind) Cleanup(args); } 1 common Cleaning class might be auto_array. SUTTER?: >> becomes simply >> >> Cleaning lady(args); >> Stuff(); >> >> (with an appropriate Cleaning dtor) without having to write the >> lady.NeverMind(); line? > HOWLETT: howlett@netcom.com (Scott Howlett) >How about... > >Cleaning::~Cleaning() >{ > if(uncaught_exception()) > Cleanup(args); >} SUTTER: herbs@cntc.com (Herb Sutter) Yup, that's what I had in mind. Now for a question that I don't know the answer to off the top of my head: Is using this idiom along with uncaught_exception() actually cheaper than using the original try/catch? I think it would definitely be cheaper with the lady.NeverMind() call, but I'm not sure what overhead may be associated with uncaught_exception() instead of a somewhat equivalent catch(...). KANZE: James Kanze I doubt that it would ever really be cheaper. With try/catch, your code has access to the original context; with this idiom, you must somehow pass the necessary context (pointers or references to the relevant variables) to Cleaning in the constructor. IMHO: this extra level of indirection hurts readability. On the other hand, the idiom does avoid some duplication of code (in the catch clause, and for the normal case). What I'd really like is some sort of "anonymous" class whose "members" are the variables, etc., visible in local scope. (Such "anonymous" classes can only exist as local types and objects.) One of the simpler variants of this would be "cleanup { ... }", which would declare a local instance of the implicit class, with the code in "{ ... }" as its destructor. A more complex variant would be "lambda ( ) { ... }", which would create a local instance of the class with an operator()( ) function, and return its address. (This is more complex because you need to be able to specify a return value, and probably, to be totally general, a base class as well.) I'll admit that even today (when it is far to late to propose an extention to the standard), my ideas about this are still too vague for a formal proposal, but the idea intrigues me. (Note how well "cleanup" fits in with the current rules concerning calling destructors during stack unwinding or leaving scope.) [ Java has a finally clause which is a block you can put in your function body and is executed no matter how the function is exitted (normally or exception). This seems nicer than an anonymous class. -adc ]