一般来说,任何
将产生文字16
,因为编译器肯定会实现称为常量折叠的优化。
的表现
可能较低,具体取决于这些变量的值存储在哪里。在记忆中?如果是这样,内存是否在任何 CPU 缓存中?或者它是否存储在 CPU 寄存器之一中?没有确定的答案。
我一般来说,对于一个特定的程序,你总是可以看到你的编译器给你什么——但请注意,这可能会根据周围的代码和你的优化标志而发生很大变化。
要自己尝试,请考虑这个小程序:
int f() { return 16; }
int g() { return 1 << 4; }
int h() { return 10 + 6; }
int i() {
int myarray[7] = { 16 };
return myarray[3];
}
int j() {
int mysixteen = 16;
return mysixteen;
}
如果我使用 gcc 4.7.2 编译它然后检查反汇编,比如
$ gcc -c so19802742.c -o so19802742.o
$ objdump --disassemble so19802742.o
我明白了:
0000000000000000 <f>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: b8 10 00 00 00 mov $0x10,%eax
9: 5d pop %rbp
a: c3 retq
000000000000000b <g>:
b: 55 push %rbp
c: 48 89 e5 mov %rsp,%rbp
f: b8 10 00 00 00 mov $0x10,%eax
14: 5d pop %rbp
15: c3 retq
0000000000000016 <h>:
16: 55 push %rbp
17: 48 89 e5 mov %rsp,%rbp
1a: b8 10 00 00 00 mov $0x10,%eax
1f: 5d pop %rbp
20: c3 retq
0000000000000021 <i>:
21: 55 push %rbp
22: 48 89 e5 mov %rsp,%rbp
25: 48 c7 45 e0 00 00 00 movq $0x0,-0x20(%rbp)
2c: 00
2d: 48 c7 45 e8 00 00 00 movq $0x0,-0x18(%rbp)
34: 00
35: 48 c7 45 f0 00 00 00 movq $0x0,-0x10(%rbp)
3c: 00
3d: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%rbp)
44: c7 45 e0 10 00 00 00 movl $0x10,-0x20(%rbp)
4b: 8b 45 ec mov -0x14(%rbp),%eax
4e: 5d pop %rbp
4f: c3 retq
0000000000000050 <j>:
50: 55 push %rbp
51: 48 89 e5 mov %rsp,%rbp
54: c7 45 fc 10 00 00 00 movl $0x10,-0x4(%rbp)
5b: 8b 45 fc mov -0x4(%rbp),%eax
5e: 5d pop %rbp
5f: c3 retq
请注意,由于不断折叠,如何f
产生完全相同的机器代码。数组访问会导致最多的机器代码(但不一定是最慢的!)并且介于两者之间。g
h
i
j
但是,这根本没有任何更复杂的代码优化!使用 eg 编译时生成的代码-O2
可能完全不同,因为编译器注意到调用这五个函数中的任何一个都等同于仅使用常量16
!