__attribute__((constructor))
是GCC和兼容的编译器中的一个特性,用于指示编译器将一个函数标记为在程序启动时自动执行的初始化函数。
同样的还有__attribute__((destructor))在main()函数后调用。
当你在一个函数声明或定义前加上__attribute__((constructor))
属性时,就会告诉编译器,在程序加载时(在main函数执行之前),需要自动调用这个函数。这个特性通常用于在程序启动时执行一些全局的初始化工作,比如注册回调函数、初始化全局变量等。
举个例子,如果你有一个函数 void my_init_function(void)
,并且你想在程序启动时自动执行它,你可以这样声明:
void my_init_function(void) __attribute__((constructor));
然后在程序加载时,my_init_function
将会被自动调用。
总的来说,__attribute__((constructor))
特性为开发者提供了一种方便的方式来定义在程序启动时自动执行的初始化函数,使得全局的初始化工作变得更加简单和方便。
__attribute__((constructor))
还可以指定优先级。
在GCC和Clang中,初始化函数的优先级是越小越先执行,而不是越大越先执行。这意味着具有较小优先级值的初始化函数会在具有较大优先级值的初始化函数之前执行。
默认情况下,没有指定优先级的初始化函数被视为具有中等优先级(0),而通过显式设置优先级,可以控制初始化函数的执行顺序。
举个例子,如果你有三个初始化函数a()
、b()
和c()
,并且你希望按照a()
-c()
-b()
的顺序执行,你可以这样定义:
void a() __attribute__((constructor(99)));
void b() __attribute__((constructor(101)));
void c() __attribute__((constructor(100)));
在这个例子中,a()
函数的优先级为101,c()
的优先级为100,b()
的优先级为99。因此,在程序启动时,它们将按照a()
-c()
-b()
的顺序执行。
需要注意的是,初始化函数的优先级仅用于确定它们的执行顺序,并不表示初始化的速度。初始化函数的执行速度取决于函数本身的实现和所涉及的操作,与优先级无关。
请记住,全局变量的初始化顺序是依赖于编译器和链接器的具体实现的,可能在不同的编译器和平台上有所不同。因此,在编写代码时,应尽量避免过于依赖全局变量之间的初始化顺序,以确保代码的可移植性和稳定性。
#include
#include
static void before(void) __attribute__((constructor));
static void before3(void) __attribute__((constructor(103)));
static void before2(void) __attribute__((constructor(102)));
static void before1(void) __attribute__((constructor(101)));
static void before2() { printf("before 102\n"); }
static void before1() { printf("before 101\n"); }
static void before3() { printf("before 103\n"); }
static void before() { printf("before main\n"); }
int main() {
printf("main\n");
return 0;
}
运行结果:
$ ./a.out
before 101
before 102
before 103
before main
main