main函数执行之前,主要就是初始化系统相关资源:
1. 设置栈指针
2. 初始化static静态和global全局变量,即data段的内容
3. 将未初始化部分的全局变量赋初值:数值型short,int,long等为0,bool为FALSE,指针为NULL,等等,即.bss段的内容
4. 全局对象初始化,在main之前调用构造函数
5. 将main函数的参数,argc,argv等传递给main函数,然后才真正运行main函数
main函数执行之后:
1. 全局对象的析构函数会在main函数之后执行;
2. 可以用atexit 注册一个函数,它会在main 之后执行;
__attribute__((constructor)) 用这个修饰函数,会让函数在main调用之前被执行
__attribute__((destructor)) 用这个修饰函数,会让函数在main调用之后被执行
#include <stdio.h>
#include <stdlib.h>
void func3();
void func4();
//__attribute__((constructor)) // 在main函数被调用之前调用
//__attribute__((destructor)) // 在main函数被调用之后调
__attribute__((constructor)) void func1()
{
printf("---------before main\n");
}
__attribute__((destructor)) void func2()
{
printf("---------after main\n");
}
void func3()
{
printf("---------call func3\n");
}
void func4()
{
printf("---------call func4\n");
}
int main(int argc, char *argv[])
{
atexit(func3);
atexit(func4);
const char *p;
p = "in main";
printf("-------------[%s]\n", p);
return 0;
}
执行结果如下
[root@localhost ~]#
[root@localhost ~]# ./a.out
---------before main
-------------[in main]
---------call func4
---------call func3
---------after main
这么看来 atexit注册的回调函数,类似栈,先进后出,先注册,但是后调用
而且 __attribute__((destructor)) 修饰的函数最后调用