我发现了一个关于局部静态变量的有趣行为。编译器每次都尝试重新加载它们。以下是代码示例。为什么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