static initialization
靜態(tài)初始化谍珊,只適用于擁有靜態(tài)存儲期(static storage duration)的變量。擁有靜態(tài)存儲期的變量是:
All objects declared at namespace scope (including global namespace) have this storage duration, plus those declared with static or extern.
舉例:
int i;
void f(){
static int j;
}
擁有靜態(tài)存儲期的變量,在程序運行之前就分配了空間囊榜。更確切的說,是在編譯成目標文件或者把可執(zhí)行文件裝載到內存中的時候分配的空間。
什么是靜態(tài)初始化呢完丽?
靜態(tài)初始化,指的是在程序開始運行之前拇舀,就對變量進行了初始化逻族。
靜態(tài)初始化包含兩種情況,zero initialization和constant initialization骄崩。
int a; // zero initialization
int b = 1; // constant initialization
zero initialization指的是初始化為0聘鳞,constant initialization指的是初始化為常量表達式的值。
造成這兩種初始化的區(qū)別的根本原因是要拂,具有靜態(tài)存儲期的變量的存儲位置不同抠璃。
眾所周知,具有靜態(tài)存儲期的變量(不考慮const)存儲在data段和bss段宇弛。其中data段存儲的是鸡典,用常量表達式初始化的變量;bss段存儲的是沒有常量表達式來初始化的變量枪芒。
- data段里面的是constant initialization的變量彻况。在編譯的時候,變量就被分配了文件空間舅踪,就被初始化好了纽甘。
- bss里面的是未初始化的變量。在編譯的時候bss段是沒有實際占用文件空間的抽碌,而是在裝載的時候才進行分配空間然后全部初始化為0悍赢。所以bss里面的變量也就是會進行zero initialization的變量。
總結來說货徙, static initialization只是針對static storage duration的變量的概念左权,分為zero initialization和constant initialization。
dynamic initialization
相對的概念痴颊,除了靜態(tài)初始化之外的全部都是動態(tài)初始化赏迟。
首先,非靜態(tài)存儲期的變量都是動態(tài)初始化蠢棱。例如:
void f(){
int i = 0;
}
其次锌杀,靜態(tài)存儲期的變量也有可能動態(tài)初始化甩栈。例如:
struct T{
int i;
T(int ii) : i(ii) { }
};
T t(0); // dynamic
int i = f(); // dynamic
void g(){
static T t(0); // dynamic
}
但是上面是的過程就不是單純的動態(tài)初始化,而是靜態(tài)初始化和動態(tài)初始化的結合糕再。首先裝載時給變量分配地址空間量没,進行zero initialization,然后程序運行時再調用(構造)函數進行dynamic initialization突想。
補充
具有靜態(tài)存儲期的變量一般都是存在data段和bss段殴蹄,但是const修飾的變量是例外。const 修飾的變量和一些字符串字面量在rodata段或者text段蒿柳,這取決于編譯器的實現饶套。對于gcc編譯器而言,這些變量在text段垒探。
對于靜態(tài)初始化,如果constant initialization的常量表達式是0的話怠李,那么編譯器一般將其視為zero initialization圾叼,即變量在bss段而非data段。這樣做有助于減小可執(zhí)行文件的大小捺癞。
例子:
int a; // bss segment
int b = 1; // data segment
int c = 0; // bss segment
const int d = 0; // text segment