tags:

views:

786

answers:

2
extern void MyInitFunc(void) __attribute__ ((constructor));
extern void MyTermFunc(void) __attribute__ ((destructor));

void MyInitFunc(void)
{
  printf("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n");
}

void MyTermFunc(void)
{
}

I put this in a .c file which is present in the main application (not a library or framework). It doesn't get called as per the GCC docs. Am I missing something important? This is on XCode 3.2 on Snow Leopard.

+8  A: 

This might explain some of the strange bugs being reported on Snow Leopard, but only if this construct worked in earlier releases.

You are correct that MyInitFunc should have been called purely as a result of being linked in with the program, even if the program is plain C89, even if the rest of it is some other language entirely.

The problem is that the C startup code on your system is not looking at the .ctors section and the .dtors section for addresses of constructors and destructors. I'm not sure if this is true of all platforms, but normally this is __do_global_ctors, a part of libgcc.

It's a platform bug, or, your gcc was built wrong, or, Apple has simply decided to do things differently and gcc doesn't support the platform properly.

You might try cc -v ... and check that collect2 is being called instead of ld directly.

DigitalRoss
+1 for answering the question despite the low acceptance rate.
Chris Lutz
I haven't tried on Snow Leopard, but I do recall using this functionality on older Mac OS Xen.
Chuck
It is documented in a technote as working and mentioned in a document I just found: Dynamic Library Programming Topics. Maybe something will click in there.
codist
It says "Note: Applications can also define and use initializer and finalizers."
codist
It doesn't mention what extra requirement is there for an application. I may have to build a library.
codist
Are you not using Mac OS X? I think you're giving reasons why it could fail, not why this person is having problems. It works fine for me.
Ken
+3  A: 

(a) Your code works for me compiling and running on SnowLeopard in Xcode 3.2.

(b) I'm not sure when stdout is guaranteed to have been set up. You're running code before main. Why not update a global variable here, then print it out in main to see if your code ran.

Ken
Not sure why this didn't work the first time. I added a new source file with the initializers, made sure it was the first file in the compile sources step, and now it works. Being the first item after the crt in the load map it loads before any of the c++ static initializers.
codist