变量引用(别名)是否会影响运行时成本?

che*_*kow 13 c++ alias runtime reference

也许这是编译器特定的东西.如果是这样,gcc(g ++)怎么样?如果您使用这样的变量引用/别名:

int x = 5;
int& y = x;
y += 10;
Run Code Online (Sandbox Code Playgroud)

它实际上需要比我们不使用引用更多的周期.

int x = 5;
x += 10;
Run Code Online (Sandbox Code Playgroud)

换句话说,机器代码是否发生变化,或者"别名"是否仅在编译器级别发生?

这似乎是一个愚蠢的问题,但我很好奇.特别是在可能暂时重命名某些成员变量以便数学代码更易于阅读的情况下.当然,我们并没有在这里谈论瓶颈......但这是我正在做的事情,所以我只是想知道是否存在任何"实际"差异......或者它是否只是化妆品.

Kor*_*icz 11

它可以被视为别名,但不是效率方面.在引擎盖下,引用是一个具有更好语法和更高安全保证的指针.因此,您有一个"取消引用"操作运行时惩罚.除非编译器优化它,但我通常不会指望它.

如果编译器是否会对其进行优化,那么除了查看生成的程序集之外别无他法.

  • 答案并不准确.引用背后的意图之一是实现别名的概念,即现有对象的替代名称.我相信这在TC++ PL中有明确说明.虽然情况并非总是如此,但"别名"仍然是对许多情况下参考文献的准确描述. (4认同)

AnT*_*AnT 5

的确,在大多数情况下,引用实现了“别名”的概念,别名是它们绑定到的对象的替代名称。

但是,通常情况下,引用是通过指针实现的。但是,一个好的编译器仅在运行时确定实际绑定的情况下才使用实际指针来实现引用。如果绑定在编译时是已知的(并且类型匹配),则编译器通常会将引用实现为同一对象的替代名称,在这种情况下,通过引用访问该对象(与访问相比不会产生性能损失)它的原始名称)。

您的示例就是您不希望参考获得任何性能损失的示例之一。


Hel*_*rld 4

我比较了 Gnu/Linux 上的 2 个程序。下面仅显示了 GCC 输出,但 clang 结果得出了相同的结论。

海湾合作委员会版本: 4.9.2

铿锵版本: 3.4.2

节目

1.cpp

#include <stdio.h>
int main()
{
    int x = 3;
    printf("%d\n", x);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

2.cpp

#include <stdio.h>
int main()
{
    int x = 3;
    int & y = x;
    printf("%d\n", y);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

考试

尝试 1:不进行优化

gcc -S --std=c++11 1.cpp

gcc -S --std=c++11 2.cpp

1.cpp 生成的程序集较短。

尝试2:优化

gcc -S -O2 --std=c++11 1.cpp

gcc -S -O2 --std=c++11 2.cpp

最终的组装结果是完全相同的。

装配输出

1.cpp,没有优化

    .file   "1.cpp"
    .section    .rodata
.LC0:
    .string "%d\n"
    .text
    .globl  main
    .type   main, @function
main:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    subq    $16, %rsp
    movl    $3, -4(%rbp)
    movl    -4(%rbp), %eax
    movl    %eax, %esi
    movl    $.LC0, %edi
    movl    $0, %eax
    call    printf
    movl    $0, %eax
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size   main, .-main
    .ident  "GCC: (Debian 4.9.2-10) 4.9.2"
    .section    .note.GNU-stack,"",@progbits
Run Code Online (Sandbox Code Playgroud)

2.cpp,没有优化

    .file   "2.cpp"
    .section    .rodata
.LC0:
    .string "%d\n"
    .text
    .globl  main
    .type   main, @function
main:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    subq    $16, %rsp
    movl    $3, -12(%rbp)
    leaq    -12(%rbp), %rax
    movq    %rax, -8(%rbp)
    movq    -8(%rbp), %rax
    movl    (%rax), %eax
    movl    %eax, %esi
    movl    $.LC0, %edi
    movl    $0, %eax
    call    printf
    movl    $0, %eax
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size   main, .-main
    .ident  "GCC: (Debian 4.9.2-10) 4.9.2"
    .section    .note.GNU-stack,"",@progbits
Run Code Online (Sandbox Code Playgroud)

1.cpp,有优化

    .file   "1.cpp"
    .section    .rodata.str1.1,"aMS",@progbits,1
.LC0:
    .string "%d\n"
    .section    .text.unlikely,"ax",@progbits
.LCOLDB1:
    .section    .text.startup,"ax",@progbits
.LHOTB1:
    .p2align 4,,15
    .globl  main
    .type   main, @function
main:
.LFB12:
    .cfi_startproc
    subq    $8, %rsp
    .cfi_def_cfa_offset 16
    movl    $3, %esi
    movl    $.LC0, %edi
    xorl    %eax, %eax
    call    printf
    xorl    %eax, %eax
    addq    $8, %rsp
    .cfi_def_cfa_offset 8
    ret
    .cfi_endproc
.LFE12:
    .size   main, .-main
    .section    .text.unlikely
.LCOLDE1:
    .section    .text.startup
.LHOTE1:
    .ident  "GCC: (Debian 4.9.2-10) 4.9.2"
    .section    .note.GNU-stack,"",@progbits
Run Code Online (Sandbox Code Playgroud)

2.cpp,有优化

    .file   "1.cpp"
    .section    .rodata.str1.1,"aMS",@progbits,1
.LC0:
    .string "%d\n"
    .section    .text.unlikely,"ax",@progbits
.LCOLDB1:
    .section    .text.startup,"ax",@progbits
.LHOTB1:
    .p2align 4,,15
    .globl  main
    .type   main, @function
main:
.LFB12:
    .cfi_startproc
    subq    $8, %rsp
    .cfi_def_cfa_offset 16
    movl    $3, %esi
    movl    $.LC0, %edi
    xorl    %eax, %eax
    call    printf
    xorl    %eax, %eax
    addq    $8, %rsp
    .cfi_def_cfa_offset 8
    ret
    .cfi_endproc
.LFE12:
    .size   main, .-main
    .section    .text.unlikely
.LCOLDE1:
    .section    .text.startup
.LHOTE1:
    .ident  "GCC: (Debian 4.9.2-10) 4.9.2"
    .section    .note.GNU-stack,"",@progbits
Run Code Online (Sandbox Code Playgroud)

结论

优化 GCC 输出时不存在运行时成本。clang 也是如此(使用版本 3.4.2 进行测试):当优化打开时,两个程序中生成的汇编代码是相同的。