我發現了一個關於局部靜態變量的有趣行爲。編譯器每次都嘗試重新加載它們。以下是代碼示例。爲什麼C中的靜態局部變量重載?
extern void extern_proc(int a, int b);
void a_proc_s() {
static int a_var = 0;
a_var++;
extern_proc(a_var, 1);
extern_proc(a_var, 2);
extern_proc(a_var, 3);
extern_proc(a_var, 4);
extern_proc(a_var, 5);
extern_proc(a_var, 6);
}
void a_proc_r() {
static int a_var = 0;
register int r_var = ++a_var;
extern_proc(r_var, 1);
extern_proc(r_var, 2);
extern_proc(r_var, 3);
extern_proc(r_var, 4);
extern_proc(r_var, 5);
extern_proc(r_var, 6);
}
功能a_proc_s
將嘗試從內存中加載a_var
每次調用extern_proc
。函數a_proc_r
將使用來自寄存器的本地副本。 爲什麼編譯器不能在前一個函數中優化這個負載?
下面是來自x86_64彙編程序的有趣片段。其他架構類似。
;Fragment for a_proc_s
movl a_proc_s.a_var(%rip), %edi
movl $2, %esi
callq extern_proc
movl a_proc_s.a_var(%rip), %edi
movl $3, %esi
callq extern_proc
;Fragment for a_proc_r
movl $2, %esi
movl %ebx, %edi
callq extern_proc
movl $3, %esi
movl %ebx, %edi
callq extern_proc
如果沒有線程特定的結構,來自不同線程的調用是未定義的行爲。編譯器可能會忽略它們。 – Michas