Date: Tue, 06 May 2003 12:50:25 -0400 From: Jason Merrill Subject: Re: __attribute__((cleanup(function)) versus try/finally Message-ID: References: MIME-Version: 1.0 Content-length: 3393 On Tue, 6 May 2003 15:20:59 +0200 (CEST), Gerald Pfeifer wrote: > For those that didn't follow gcc-patches, there has been strong > disagreement on how to implement exception handling in C for some > time now: > > o RTH (and others) are strongly in favor of try/finally, which is > implemented by several others compilers. Myself among them. try/finally is well defined, and already implemented in other languages and other C compilers. IMO the explicit syntax is in keeping with the spirit of C. If we have any exception handling support whatsoever in C, it should be try/finally. And we've (for some definition of we) always intended to have some EH in C someday. Now that we're trying to integrate pthreads with EH, it's time. > o Mark (and others) are against adding try/finally and favor adding > a different extension: __attribute__((cleanup(function)) which is > "lighter" in a sense. I agree with Alex's comments on this approach; it's trying to introduce the C++ object model into C, which seems like rather a backwards way to approach exception cleanliness. FWIW, here's a post to the glibc list from someone who worked on threading in Tru64, the closest thing to a prior implementation. http://sources.redhat.com/ml/libc-alpha/1999-08/msg00038.html Here's the beginning of the try/finally thread: http://gcc.gnu.org/ml/gcc-patches/2002-11/threads.html#00239 Which includes the message Michael mentions: http://gcc.gnu.org/ml/gcc-patches/2002-11/msg00451.html To sum up, the objections to try/finally amounted to: 1) -fexceptions overhead On any modern OS, the overhead is only on disk unless EH constructs are actually used. The unwind tables are only loaded if an exception is thrown. By contrast, registering pthread cleanups to work with the longjmp_unwind solution involves a setjmp, which needs to run whether or not you throw an exception. 2) implementing something before standardization That's why the patch doesn't create "try" and "finally" keywords, but rather "__try" and "__finally". Though I can't imagine any similar construct having different semantics. 3) poorly defined semantics Nonsense. As I wrote early in the thread: The code in the finally block is run on exit from the try block, except that exiting a try block with a corresponding finally block via longjmp or computed goto has undefined behavior. It's simple, it's straightforward, it shares implementation with the Java frontend. There's tons of prior art. 4) it's the wrong choice Other proposed solutions were: adding destructors to C (i.e. attribute cleanup), Again, I don't want to get into object lifetime stuff in C. try/catch instead C++ doesn't have try/finally because it has destructors. C doesn't need catch for pthreads, but we could implement it later if we want full EH in C. specialized pthread primitive builtins ...which would be modelled internally with TRY_FINALLY_EXPR. I could accept this, but I'd rather provide the more general facility and let the pthreads library worry about pthreads semantics. longjmp_unwind ...which has now been implemented, though I don't think the pthread library uses it yet. IMO none of these are nearly as clean in design as try/finally. Any one of them will be more of a maintenance headache. Jason