模仿C中的静态对象的构造函数

Chi*_*Lan 5 c c++ constructor

我想要一个全局names变量,看起来像这样

char* names[NAMES_CAP];
int names_len = 0;
Run Code Online (Sandbox Code Playgroud)

我希望每个链接到此库的人都能够将项目添加到此列表中.

很容易做到这一点main.

int main(int argc,char**argv) {
    names[names_len++] = "new name";
    names[names_len++] = "new name 2";
}
Run Code Online (Sandbox Code Playgroud)

但是如果我想要堆叠两个库怎么办?(即,我的库,libnames保存全局变量.如果有人链接到libnameuser谁使用libnames,它将自动添加定义libnameusernames数组中的所有名称libnames.

有没有办法做到这一点?

在C++中,我可以将其插入names[names_len++] = "..."到全局对象的构造函数中,并且必须调用它.但我可以用普通的C做到这一点吗?

Joe*_*Joe 2

更新:请参阅/sf/answers/167343851/了解此答案的更新版本。

下面是一个预处理器抽象,用于支持 GCC 和 MSVC 的 C 静态初始化函数。GCC 版本还可以与 LLVM CC 一起使用,也许还可以与其他一些编译器一起使用。

MSVC 版本的工作原理是将 ptr 放置到由应用程序或 DLL 启动代码处理的特殊部分中的静态初始化函数。

#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"; }
Run Code Online (Sandbox Code Playgroud)