进程的启动销毁流程及static变量的构造析构时机

本文为探究static变量构造、析构时机,从而整理了相关的进程启动销毁流程。最后介绍由static变量销毁机制导致的bug,引入google针对此问题设置的编程规范。

一、一个进程的启动销毁流程:

  1. 加载程序和库:当程序开始执行时,操作系统将程序加载到内存中,并加载所有需要的库。
  2. 初始化全局变量(包括全局静态变量):在加载程序时,编译器会为所有全局变量分配内存,调用它们的构造函数。
  3. 执行main函数:在全局变量构造完成后,程序会执行main函数。
  4. 初始化局部变量(包括局部静态变量):运行到局部静态变量位置,构造一次。
  5. 执行return 0:当main()函数执行到return语句时,程序会将返回值传递给exit()函数,并且调用所有已注册的函数,最终退出程序

二、全局变量、static全局变量、static局部变量构造析构顺序

  1. main函数入口前:全局变量和全局静态变量构造
    同一个文件内的全局对象,初始化的顺序与他们声明的顺序是一致的(销毁的顺序则相反)。而对于不同文件间的全局对象,c++ 标准并没有明确规定它们之间的初始化(销毁)顺序应该怎样,因此实现上完全由编译器自己决定。编译器会维护一个析构函数的函数指针栈,一旦构造完成,就会把相应的析构函数指针放到这个栈中
  2. main函数内:初始化static局部变量,同时将变量的析构函数存入编译器维护的指针表
  3. return 0后:析构所有全局变量与局部静态变量,由编译器生成的exit函数会逐个调用(按照注册顺序)函数指针栈中的析构函数

三、静态变量导致的bug

静态变量A析构函数中调用了静态变量B的函数:由于析构顺序不一定,调用时B可能依据被析构了,因此导致了程序崩溃。

四、google针对静态对象的编程规范

不允许声明类的静态变量和类的全局变量,这是因为这样会引起构造函数和析构函数执行顺序的混乱。

参考资料:

1、Google C++编程规范 – 第二十八条 -《静态变量和全局变量》
2、C++全局对象,静态局部对象,自动局部对象构造析构顺序
3、__do_global_dtors_aux和__do_global_ctors_aux作用

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值