main与对象初始化 in C++

    没有学过代码编译的原理,以前也没有兴趣去学编译器的相关原理,但是近期通过阅读google开源项目gtest,对我稍有触动。

代码:

main

image

test示例

image

TEST宏定义

#define TEST(test_case_name, test_name)\
GTEST_TEST_(test_case_name, test_name, \
::testing::Test, ::testing::internal::GetTestTypeId())

GTEST_TEST_宏定义:

#define GTEST_TEST_(test_case_name, test_name, parent_class, parent_id)\
class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\
public:\
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\
private:\
virtual void TestBody();\
static ::testing::TestInfo* const test_info_;\
GTEST_DISALLOW_COPY_AND_ASSIGN_(\
GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\
};\
\
::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\
::test_info_ =\
::testing::internal::MakeAndRegisterTestInfo(\
#test_case_name, #test_name, "", "", \
(parent_id), \
parent_class::SetUpTestCase, \
parent_class::TearDownTestCase, \
new ::testing::internal::TestFactoryImpl<\
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\
void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()

 

google通过一系列的宏和模板类实现了不同test的自动注册。run时一个一个调用test的run就行了。那么google是怎么实现调用前自动注册的呢?

设置两个断点:断点一、main;断点二、MakeAndRegisterTestInfo

运行顺序:

先运行到断点二

image

再运行到断点一

image

网上找到的解释:

对于全局对象(global object),VC下是先定义先初始化,但C++标准没做规定。全局对象默认是静态的,全局静态(static)对象必须在main()函数前已经被构造,告知编译器将变量存储在程序的静态存储区,由C++ 编译器startup代码实现。startup代码是更早于程序进入点(main 或WinMain)执行起来的代码,它能做些像函数库初始化、进程信息设立、I/O stream产生等等动作,以及对static对象的初始化动作(也就是调用其构造函数);在main()函数结束后调用它的析构函数。

C/C++程序的启动代码通常包含以下行为,并且按照所列的次序执行:
1、禁止所有中断。
2、从ROM 里复制所有初始化数据到RAM 里。
3、把未初始化数据区清零。
4、未堆栈分配空间并初始化。
5、初始化处理器堆栈指针。
6、创建并初始化堆。
7、(只对C++有效)对所有全局变量执行构造函数和初始化函数。
8、允许中断。
9、调用main。

 

注意点:

全局变量的初始化顺序是不确定的。

编译器不能定义不同编译单元全局变量的初始化顺序。

在同一个cpp文件里,编译器会保证按照他们出现的顺序初始化。但是如果两个全局变量在不同的编译单元,编译器不能控制他们的构造顺序,我们需要想办法确定他们的构造顺序。本人曾经因为这个问题导致过程序崩溃,所以记忆尤为深刻,在此特意提一下。

关于这一块的讨论,可以参考博文:http://blog.chinaunix.net/uid-26611383-id-3898563.html

转载于:https://www.cnblogs.com/liaokang/p/4057150.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值