objdump 的反汇编输出可能会给你一些关于编译器(gcc,在这种情况下)如何处理这种情况的提示:
$ objdump -d a.out
...
000000000040050c <main>:
40050c: 55 push %rbp
40050d: 48 89 e5 mov %rsp,%rbp
400510: 8b 05 fa 03 20 00 mov 0x2003fa(%rip),%eax # 600910 <x.2163>
400516: 89 c6 mov %eax,%esi
400518: bf fc 05 40 00 mov $0x4005fc,%edi
40051d: b8 00 00 00 00 mov $0x0,%eax
400522: e8 b9 fe ff ff callq 4003e0 <printf@plt>
400527: 8b 05 e7 03 20 00 mov 0x2003e7(%rip),%eax # 600914 <x.2162>
40052d: 89 c6 mov %eax,%esi
40052f: bf fc 05 40 00 mov $0x4005fc,%edi
400534: b8 00 00 00 00 mov $0x0,%eax
400539: e8 a2 fe ff ff callq 4003e0 <printf@plt>
40053e: b8 00 00 00 00 mov $0x0,%eax
400543: 5d pop %rbp
400544: c3 retq
使用readelf,我们可以发现每个x在最终的可执行文件中都有自己的符号:
$ readelf -s a.out
...
45: 0000000000600910 4 OBJECT LOCAL DEFAULT 25 x.2163
46: 0000000000600914 4 OBJECT LOCAL DEFAULT 25 x.2162
这里是 C 代码:
int main()
{
static int x = 8;
{
static int x = 9;
printf("%d",x);
}
printf("%d",x);
return 0;
}