两种方法的优点和缺点是什么:
Case#1: const int& x = 5;
vs
Case#2: const int x = 5;
我知道在案例#1中,x指的是可执行文件中的一个位置,我相信案例#2中的x也是如此。
为什么要使用一个而不是另一个?
答案 0 :(得分:1)
使用gcc explorer:
案例1(-O3):
main: # @main
xorl %eax, %eax
ret
global_constant:
.quad reference temporary for global_constant
reference temporary for global_constant:
.long 2048 # 0x800
案例2(-O3):
main: # @main
xorl %eax, %eax
ret
使用Mingw 4.8.1 g ++ Windows 8(同样的结果看起来更混乱)..
案例1(-O3):
.file "TestConstantsAsm.cpp"
.def __main; .scl 2; .type 32; .endef
.section .text.startup,"x"
.p2align 4,,15
.globl main
.def main; .scl 2; .type 32; .endef
.seh_proc main
main:
subq $40, %rsp
.seh_stackalloc 40
.seh_endprologue
call __main
xorl %eax, %eax
addq $40, %rsp
ret
.seh_endproc
.p2align 4,,15
.def _GLOBAL__sub_I_global_constant; .scl 3; .type 32; .endef
.seh_proc _GLOBAL__sub_I_global_constant
_GLOBAL__sub_I_global_constant:
.seh_endprologue
leaq _ZGR15global_constant0(%rip), %rax
movq %rax, global_constant(%rip)
ret
.seh_endproc
.section .ctors,"w"
.align 8
.quad _GLOBAL__sub_I_global_constant
.globl global_constant
.bss
.align 16
global_constant:
.space 8
.data
.align 4
_ZGR15global_constant0:
.long 2048
.ident "GCC: (rev5, Built by MinGW-W64 project) 4.8.1"
案例2(-O3):
.file "TestConstantsAsm.cpp"
.def __main; .scl 2; .type 32; .endef
.section .text.startup,"x"
.p2align 4,,15
.globl main
.def main; .scl 2; .type 32; .endef
.seh_proc main
main:
subq $40, %rsp
.seh_stackalloc 40
.seh_endprologue
call __main
xorl %eax, %eax
addq $40, %rsp
ret
.seh_endproc
.ident "GCC: (rev5, Built by MinGW-W64 project) 4.8.1"
没有(-O3),第二种情况仍然比第一种情况好。它总是......
我使用的命令是:
g++ -S -O3 TestConstantsAsm.cpp
g++ -S -O2 TestConstantsAsm.cpp
g++ -S -O TestConstantsAsm.cpp
,程序是:
const int& global_constant = 2048;
int main()
{
}
和
const int global_constant = 2048;
int main()
{
}
即使您在主要内部std::cout<<global_constant<<"\n";
(在两种情况下),案例2的程序集仍然比案例1更清晰。
答案 1 :(得分:0)
使用Visual C ++ 2013,以调试模式编译。
<案例1以下代码:
const int& VALUE = 2048;
int main() {
int A = VALUE;
return 0;
}
...生成此程序集输出:
1: const int& VALUE = 2048;
013F1380 55 push ebp
013F1381 8B EC mov ebp,esp
013F1383 81 EC C0 00 00 00 sub esp,0C0h
013F1389 53 push ebx
013F138A 56 push esi
013F138B 57 push edi
013F138C 8D BD 40 FF FF FF lea edi,[ebp-0C0h]
013F1392 B9 30 00 00 00 mov ecx,30h
013F1397 B8 CC CC CC CC mov eax,0CCCCCCCCh
013F139C F3 AB rep stos dword ptr es:[edi]
013F139E C7 05 34 91 3F 01 00 08 00 00 mov dword ptr ds:[13F9134h],800h
013F13A8 C7 05 30 91 3F 01 34 91 3F 01 mov dword ptr ds:[13F9130h],13F9134h
013F13B2 5F pop edi
013F13B3 5E pop esi
013F13B4 5B pop ebx
013F13B5 8B E5 mov esp,ebp
013F13B7 5D pop ebp
013F13B8 C3 ret
(...)
2:
3: int main() {
00C42280 55 push ebp
00C42281 8B EC mov ebp,esp
00C42283 81 EC CC 00 00 00 sub esp,0CCh
00C42289 53 push ebx
00C4228A 56 push esi
00C4228B 57 push edi
00C4228C 8D BD 34 FF FF FF lea edi,[ebp-0CCh]
00C42292 B9 33 00 00 00 mov ecx,33h
00C42297 B8 CC CC CC CC mov eax,0CCCCCCCCh
00C4229C F3 AB rep stos dword ptr es:[edi]
4: int A = VALUE;
00C4229E A1 30 91 C4 00 mov eax,dword ptr ds:[00C49130h]
00C422A3 8B 08 mov ecx,dword ptr [eax]
00C422A5 89 4D F8 mov dword ptr [A],ecx
5: return 0;
00C422A8 33 C0 xor eax,eax
6: }
00C422AA 5F pop edi
6: }
00C422AB 5E pop esi
00C422AC 5B pop ebx
00C422AD 8B E5 mov esp,ebp
00C422AF 5D pop ebp
00C422B0 C3 ret
在情况1中,值2048(0x800)存储在内存中,当在主代码中引用常量时,将访问该值。
<案例2以下代码:
const int VALUE = 2048;
int main() {
int A = VALUE;
return 0;
}
...生成此程序集输出:
1: const int VALUE = 2048;
2:
3: int main() {
00F02280 55 push ebp
00F02281 8B EC mov ebp,esp
00F02283 81 EC CC 00 00 00 sub esp,0CCh
00F02289 53 push ebx
00F0228A 56 push esi
00F0228B 57 push edi
00F0228C 8D BD 34 FF FF FF lea edi,[ebp-0CCh]
00F02292 B9 33 00 00 00 mov ecx,33h
00F02297 B8 CC CC CC CC mov eax,0CCCCCCCCh
00F0229C F3 AB rep stos dword ptr es:[edi]
4: int A = VALUE;
00F0229E C7 45 F8 00 08 00 00 mov dword ptr [A],800h
5: return 0;
00F022A5 33 C0 xor eax,eax
6: }
00F022A7 5F pop edi
00F022A8 5E pop esi
00F022A9 5B pop ebx
00F022AA 8B E5 mov esp,ebp
00F022AC 5D pop ebp
00F022AD C3 ret
在案例2中,没有为全局常量声明本身生成代码。当使用常量时,它只是一个“立即移动”指令,它将值2048(0x800)直接插入变量中。如果未使用常量,则根本不会出现在装配中。