优点和缺点...常数作为价值还是作为参考?

时间:2014-03-01 19:13:42

标签: c++

两种方法的优点和缺点是什么:

Case#1: const int& x = 5;

vs

Case#2: const int x = 5;

我知道在案例#1中,x指的是可执行文件中的一个位置,我相信案例#2中的x也是如此。

为什么要使用一个而不是另一个?

2 个答案:

答案 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)直接插入变量中。如果未使用常量,则根本不会出现在装配中。