zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    系统数据库如何恢复Master数据库
    在Orderby子句中使用CASE 语句
    SQL NOTECURSOR
    MVC 中静态文件部分动态化
    SQL NOTCTE
    Get data style from Excel
    SQL NOTPARTITION
    LAMDA表达式学习
    SQL NOTEVARIABLE
    起II6.0中使用windows2003自带的虚拟主机管理系统
  • 原文地址:https://www.cnblogs.com/liaokang/p/4057150.html
Copyright © 2011-2022 走看看