零配置初始化流程?
零初始化的規則:
如果是標準類型,就會初始化為0
如果是非union的類類型,基類和非靜態成員初始化為零,所有填充位初始化為零。忽略構造函數
如果是union,第一個非靜態的數據初始化為零,填充位初始化為零
如果是數組,所有元素初始化為零
如果是引用,不做任何處理
說明
在非局部初始化中,static和thread-local變量,如果不是const類型,會在其他初始化之前進行零初始化。如果非類類型的變量,也不是局部變量,并且沒有初始化器,那么默認初始化不做任何事情,也就是由一開始初始化為0,最后結果并不會修改,還是保持原來的值-零。
零初始化的指針是空指針,即使空指針不是零。
非局部變量
非局部變量,基本上遇到的就是全局變量,寫在類、函數之外的變量,總結一句就是會初始化為0,數字是0,字符是\0,指針是null
所有的有著靜態存儲期的非局部變量都會在程序起來時初始化,也就是在main函數運行之前(除非你可以延遲初始化)。所有的有著thread-local存儲期的非局部變量在線程起來時初始化,順序在執行線程函數之前。對于這兩種變量,有著兩個初始化階段:
靜態初始化
靜態初始化有兩種形勢:
如果是左值,就進行常量初始化
否則,非局部的static和thread-local進行零初始化
實際情況:
常量初始化經常在編譯期進行。將提前計算的對象作為程序的一部分存儲起來。如果編譯器沒有這樣做,那也必須保證初始化在動態初始化之前。
用來零初始化的數據保存在程序的.bss段,不占用硬盤空間,在系統加載程序的時候設置為0
class A {
public:
int i;
};
class B {
public:
B() {}
int i;
};
enum C
{
C1 = 10,
C2
};
int t;
int a[2];
A a1;
B b1;
C c;
int* p;
int main() {
cout << t << endl;
cout << a[0] << "|" << a[1] << endl;
cout << a1.i << endl;
cout << b1.i << endl;
cout << c << endl;
cout << p << endl