Skip to content

Instantly share code, notes, and snippets.

@mrexodia
Created November 26, 2024 14:28
Show Gist options
  • Save mrexodia/2595a3199c7aea00cdc5b9324c84e73d to your computer and use it in GitHub Desktop.
Save mrexodia/2595a3199c7aea00cdc5b9324c84e73d to your computer and use it in GitHub Desktop.
Portable static constructor in C for MSVC, GCC and Clang (Windows, Linux, macos)
#include <stdio.h>
extern void mylib_test();
int main()
{
puts("Hello, world!");
// NOTE: Your project must use at least one symbol from the static library
mylib_test();
}
// Reference: https://stackoverflow.com/a/2390626/1806760
// Initializer/finalizer sample for MSVC and GCC/Clang.
// 2010-2016 Joe Lowe. Released into the public domain.
#ifdef __cplusplus
#define INITIALIZER(f) \
static void f(void); \
struct f##_t_ { f##_t_(void) { f(); } }; static f##_t_ f##_; \
static void f(void)
#elif defined(_MSC_VER)
#pragma section(".CRT$XCU",read)
#define INITIALIZER2_(f,p) \
static void f(void); \
__declspec(allocate(".CRT$XCU")) void (*f##_)(void) = f; \
__pragma(comment(linker,"/include:" p #f "_")) \
static void f(void)
#ifdef _WIN64
#define INITIALIZER(f) INITIALIZER2_(f,"")
#else
#define INITIALIZER(f) INITIALIZER2_(f,"_")
#endif
#else
#define INITIALIZER(f) \
static void f(void) __attribute__((__constructor__)); \
static void f(void)
#endif
#include <stdio.h>
#include <stdlib.h>
static void mylib_finalize(void)
{
printf("finalize\n");
}
INITIALIZER(mylib_initialize)
{
printf("initialize\n");
atexit(mylib_finalize);
}
void mylib_test()
{
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment