I want to have a global names variable, which looks like that
char* names[NAMES_CAP];
int names_len = 0;
And I want every one who links to this library to be able to add an item to this list.
It's easy to do that from main.
int main(int argc,char**argv) {
names[names_len++] = "new name";
names[names_len++] = "new name 2";
}
but what if I want to stack up two libraries? (ie, my library, libnames holds the global variable. And if someone links to libnameuser who uses libnames, it will automatically add all names defined in libnameuser to the names array in libnames.
Is there any way to do that?
In C++, I can insert the names[names_len++] = "..." to the constructor of a global object, and it must be called. But can I do that with plain C?
If you are using gcc you can use the constructor attribute __attribute__((constructor)) to get the same effect. This is however non-standard C.
I would however recommend against this pattern since there is no control of ordering of any function run before main. I would rather find a nice method of hooking in all the "constructor" functions after main has started running.
Update: Refer to https://stackoverflow.com/a/2390626/270788 for updated version of this answer.
Below is a pre-processor abstration to support C static initializer functions with GCC and MSVC. The GCC version will also work with LLVM CC, maybe some other compilers as well.
The MSVC version works by placing a ptr to the static initializer function in a special section that is processed by the application or DLL startup code.
#if defined(__GNUC__)
#define INITIALIZER(f) \
static void f(void) __attribute__((constructor)); \
static void f(void)
#elif defined(_MSC_VER)
#define INITIALIZER(f) \
static void __cdecl f(void); \
__declspec(allocate(".CRT$XCU")) void (__cdecl*f##_)(void) = f; \
static void __cdecl f(void)
#endif
INITIALIZER(initializer_1) { names[names_len++] = "new name"; }
INITIALIZER(initializer_2) { names[names_len++] = "new name 2"; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With