Verification and usage summary of __attribute__ ((constructor))
Note that this is an extension of GCC and will not work everywhere.
main.c
#include <stdio.h>
__attribute__((constructor))
static void constructor() {
puts("constructor");
}
__attribute__((destructor))
static void destructor() {
puts("destructor");
}
int main(int argc, char const* argv[])
{
puts("call main");
return 0;
}
Build and execution results
$ gcc main.c && ./a.out
constructor
call main
destructor
main.c
#include <stdio.h>
int main(int argc, char const* argv[])
{
puts("call main");
return 0;
}
sharedlib.c
#include <stdio.h>
__attribute__((constructor))
static void constructor() {
puts("constructor");
}
__attribute__((destructor))
static void destructor() {
puts("destructor");
}
Build and execution results
$ gcc -shared -fPIC sharedlib.c -o libconstructor.so
$ gcc main.c -L . -lconstructor
$ LD_LIBRARY_PATH=. ./a.out
constructor
call main
destructor
By using LD_PRELOAD, it is possible to add processing to any program later.
main.c
#include <stdio.h>
int main(int argc, char const* argv[])
{
puts("call main");
return 0;
}
preload.c
#include <stdio.h>
__attribute__((constructor))
static void constructor() {
puts("constructor");
}
__attribute__((destructor))
static void destructor() {
puts("destructor");
}
Build and execution results
$ gcc main.c && ./a.out
call main
$ gcc -shared -fPIC preload.c -o preload.so
$ LD_PRELOAD=./preload.so ./a.out
constructor
call main
destructor
__attribute__ ((constructor))
It works fine even if there are multiple __attribute__ ((constructor))
.
(However, the execution order is unknown, and it seems better to avoid processes that depend on the execution order.)
main.c
#include <stdio.h>
__attribute__((constructor))
static void constructor1() {
puts("constructor1");
}
__attribute__((destructor))
static void destructor1() {
puts("destructor1");
}
int main(int argc, char const* argv[])
{
puts("call main");
return 0;
}
preload.c
#include <stdio.h>
__attribute__((constructor))
static void constructor2() {
puts("constructor2");
}
__attribute__((destructor))
static void destructor2() {
puts("destructor2");
}
Build and execution results
$ gcc main.c && ./a.out
constructor1
call main
destructor1
$ gcc -shared -fPIC preload.c -o preload.so
$ LD_PRELOAD=./preload.so ./a.out
constructor2
constructor1
call main
destructor1
destructor2
Call a function before main ()-bk blog c++ - How exactly does attribute((constructor)) work? - Stack Overflow Try using attribute ((constructor)) from GCC: Book of Days gcc - C++ static initialization vs attribute((constructor)) - Stack Overflow