Type mismatch in __cxa_atexit and __cxa_finalize

Matt Austern austern at apple.com
Thu Feb 26 23:11:14 UTC 2004


Maybe this is old news; I'm sure everyone who has implemented atexit in 
terms of __cxa_atexit must have noticed it already.

The ABI document says that atexit should be implemented so that 
atexit(f) invokes __cxa_atexit(f, 0, 0).  That doesn't quite work, 
though, because the two functions have different signatures: void 
(*)(void) versus void (*)(void*).  We can get around that by casting, 
but...

The ABI document also says that __cxa_finalize should invoke each 
function.  It doesn't explicitly say that it should invoke each 
function with its matching parameter, but that's the obvious 
interpretation.  Again, though: you can't very well write (*f)(p) if f 
is a function that takes no arguments, as will be the case whenever 
__cxa_atexit is invoked via atexit.

The obvious fix would be to say that:
  1. atexit(f) invokes __cxa_atexit((void(*)(void*)) f, 0, 0).
  2. If you're passing __cxa_atexit a function that does take an 
argument, the parameter may not be 0.
  3. When __cxa_finalize invokes a function f on a parameter p, it 
should do the equivalent of:
      if (p)
         (*f)(p);
      else
        (*((void (*)(void)) f))();

At least that's the simplest fix I can think of that doesn't make major 
changes to the interface.  But whatever fix we use, the ABI should 
probably be explicit about this.

			--Matt




More information about the cxx-abi-dev mailing list