最近正在学习openwrt源码中的netifd这个进程的实现,下载了源码之后便开始从main函数着手分析代码。我看到在main函数中,使用了几个全局的数据结构,但main函数并未对他们做初始化就直接使用了,这对我来说相当诡异。我在代码中搜索到了这几个全局结构的初始化函数,但是没有谁调用他们,后来注意到这些初始化函数都被__attribute__ ((constructor))修饰,从名字就看得出这是一系列的构造函数,我瞬间感觉世界太美好了,原来在main函数之前还能做一些事情。
下面通过一个简单的例子介绍一下gcc的__attribute__ ((constructor))属性的作用。
gcc允许为函数设置__attribute__ ((constructor))和__attribute__ ((destructor))两种属性,顾名思义,就是将被修饰的函数作为构造函数或析构函数。程序员可以通过类似下面的方式为函数设置这些属性:
void funcBeforeMain() __attribute__ ((constructor));
void funcAfterMain() __attribute__ ((destructor));
也可以放在函数名之前:
void __attribute__ ((constructor)) funcBeforeMain();
void __attribute__ ((destructor)) funcAfterMain();
带有(constructor)属性的函数将在main()函数之前被执行,而带有(destructor)属性的函数将在main()退出时执行。
下面给出一个简单的例子:
- #include <stdio.h>
- void
- __attribute__((constructor)) funcBeforeMain()
- {
- printf("%s...\n", __FUNCTION__);
- }
- void
- __attribute__((destructor)) funcAfterMain()
- {
- printf("%s...\n", __FUNCTION__);
- }
- int main()
- {
- printf("main...\n");
- return 0;
- }
编译并运行程序:
[root@ubuntu workshop]# gcc constructor.c -o constructor
[root@ubuntu workshop]# ./constructor
funcBeforeMain...
main...
funcAfterMain...
[root@ubuntu workshop]# ./constructor
funcBeforeMain...
main...
funcAfterMain...
通过程序运行结果可知,设置了constructor属性的funcBeforeMain()函数在程序进入main()函数之前就被调用了,而设置了destructor属性的funcAfterMain()函数在main()函数返回后被调用。