EH in C (was: Re: (lack of) Thread-safe exceptions on AIX (gcc-2.95.1)

Zack Weinberg zack@wolery.cumb.org
Tue Feb 1 14:11:00 GMT 2000


On Tue, Feb 01, 2000 at 02:32:52PM -0700, llewelly@198.dsl.xmission.com wrote:
> On Tue, 1 Feb 2000, Zack Weinberg wrote:
> > On Tue, Feb 01, 2000 at 12:49:01PM -0800, Bill Tutt wrote:
> > > Unless of course you do want to give C some understanding of the C++
> > > exception state, which I haven't seen anyone even come close to
> > > suggesting.
> > 
> > I believe that is exactly what people want.  To be more specific,
> > system libraries written in C need to be able to generate exceptions
> > in a C++ compatible fashion, and cope with exceptions thrown through
> > them from callbacks.  The pthreads library is the obvious example
> > since it has a pseudo- exception facility built in
> > (pthread_cleanup_push).
> 
> Currently, you can compile C code with -fexceptions, and throw C++
>   exceptions across the resulting functions. I have found this to very
>   useful, even necessary at times. 

Yes.  Of course, to extend C for exceptions, we'd have to turn on
-fexceptions for C, and the code size increase was judged to be
unacceptable.

It seems to me that the .eh_frame information could be shrunk down
substantially by not emitting unwind data for positions where we know
an exception can't be generated.  Example:

extern void f(int x) throw ();
extern void g(int x);

void h(void)
{
  f(1);
  g(2);
}

compiles as:

.globl h__Fv
        .type    h__Fv,@function
h__Fv:
.LFB1:
        subl    $24, %esp
        pushl   $1
.LCFI0:
.LCFI1:
        call    f__Fi
        subl    $12, %esp
        pushl   $2
.LCFI2:
.LCFI3:
        call    g__Fi
        addl    $44, %esp
        ret
.LCFI4:
.LFE1:

plus 60 bytes of frame info.  It is so large at least partially
because we have emitted instructions on how to unwind the stack from
any point in the function.  But the only place in this function that
can throw is the call to g__Fi, so most of it is unnecessary.  (Mind,
I have no idea how much smaller it'd get if we did that optimization.
Is there a disassembler for DWARF2 anywhere?)

...
> >   __try {
> >      /* code */
> 
> Perhaps I shouldn't open my mouth and stick my foot in it again, but
>   aren't you missing a '__throw;' here, so the cleanup code will get
>   called even if an exception is thrown? That way you don't need two sets
>   of cleanup code. (of course, there is the performance penaly of the
>   __throw;)

In this example, not if I want to return normally from the function.
The catch handler did a rethrow.

zw


More information about the Gcc mailing list