c++ 在main 之前的全局对象

问题:
google c++ 编程规范要求全局对象,应该用指针代替。指出类的构造函数在 main 之前执行是一个未定义的行为。

查看资料之后,两大主流编译器 g++ , vs它们对于全局对象的处理是这样的。。。

在 main() 函数开始之前先执行了一个 _start() 的函数。这个函数做了一些运行程序的初始化的操作。
证明:

class Test
{
public:
    Test()
    {
        std::cout << "Test construct" << std::endl;
    }
};


Test a;

int main()
{
    std::cout << "main is start" << std::endl;
}

g++ test.cpp -std=c++11 -nostdlib
报错找不到入口函数 _start。
并且可定看到全局对象 std::cout 这些对象找不到。那说明在 _start 里有构造一个全局的 std::cout .

/usr/bin/ld: warning: cannot find entry symbol _start; defaulting to 00000000004001b4
/tmp/ccYGqkKV.o:在函数‘main’中:
test.cpp:(.text+0xa):对‘std::cout’未定义的引用
test.cpp:(.text+0xf):对‘std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)’未定义的引用
test.cpp:(.text+0x14):对‘std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)’未定义的引用
test.cpp:(.text+0x1c):对‘std::ostream::operator<<(std::ostream& (*)(std::ostream&))’未定义的引用
/tmp/ccYGqkKV.o:在函数‘__static_initialization_and_destruction_0(int, int)’中:
test.cpp:(.text+0x4a):对‘std::ios_base::Init::Init()’未定义的引用
test.cpp:(.text+0x4f):对‘__dso_handle’未定义的引用
test.cpp:(.text+0x59):对‘std::ios_base::Init::~Init()’未定义的引用
test.cpp:(.text+0x5e):对‘__cxa_atexit’未定义的引用
/tmp/ccYGqkKV.o:在函数‘Test::Test()’中:
test.cpp:(.text._ZN4TestC2Ev[_ZN4TestC5Ev]+0x12):对‘std::cout’未定义的引用
test.cpp:(.text._ZN4TestC2Ev[_ZN4TestC5Ev]+0x17):对‘std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)’未定义的引用
test.cpp:(.text._ZN4TestC2Ev[_ZN4TestC5Ev]+0x1c):对‘std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)’未定义的引用
test.cpp:(.text._ZN4TestC2Ev[_ZN4TestC5Ev]+0x24):对‘std::ostream::operator<<(std::ostream& (*)(std::ostream&))’未定义的引用
/usr/bin/ld: a.out: hidden symbol `__dso_handle' isn't defined
/usr/bin/ld: 最终连接失败: 错误的值
collect2: error: ld returned 1 exit status

主要工作:
1.设置栈指针
2.初始化static静态和global全局变量,即data段的内容
3.将未初始化部分的赋初值:数值型short,int,long等为0,bool为FALSE,指针为NULL,等等,即.bss段的内容
4.运行全局构造器,估计是C++中构造函数之类的吧
5.将main函数的参数,argc,argv等传递给main函数,然后才真正运行main函数

总结:
不同的编译器对于 main 之前调用的函数可能不同。但是所做的事情基本一样。都会调用全局对象的构造函数。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章