Ich verglich 2 Programme auf GNU/Linux. Im Folgenden wird nur die GCC-Ausgabe gezeigt, aber die Ergebnisse führen zu identischen Ergebnissen.
GCC Version:4.9.2
Clang Version:3.4.2
Die Programme
1.cpp
#include <stdio.h>
int main()
{
int x = 3;
printf("%d\n", x);
return 0;
}
2.cpp
#include <stdio.h>
int main()
{
int x = 3;
int & y = x;
printf("%d\n", y);
return 0;
}
Der Test
Versuch 1: Keine Optimierungen
gcc -S --std=c++11 1.cpp
gcc -S --std=c++11 2.cpp
1.cpp die resultierende Anordnung kürzer war.
Versuch 2: Optimizations auf
gcc -S -O2 --std=c++11 1.cpp
gcc -S -O2 --std=c++11 2.cpp
Die resultierende Anordnung war völlig identisch.
Der Montage Ausgang
1.cpp, keine Optimierung
.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
2.cpp, keine Optimierung
.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
1.cpp mit Optimierungen
.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
2.cav, mit Optimierungen
.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
Fazit
Es gibt keine Laufzeitkosten, wenn es um optimierte GCC Ausgang kommt. Dasselbe gilt für den Clam (getestet mit Version 3.4.2): Wenn Optimierungen aktiviert sind, ist der generierte Assembly-Code in beiden Programmen identisch.
Gute Antwort. Danke – cheshirekow
Die Antwort ist nicht genau genau. Eine der Absichten hinter Referenzen besteht darin, das Konzept eines Alias, alternativen Namens für ein existierendes Objekt, zu implementieren. Ich glaube, das ist explizit in TC++ PL angegeben. Während dies nicht immer der Fall ist, ist "Alias" immer noch eine genaue Beschreibung dessen, was Referenzen in vielen Fällen sind. – AnT
@AndreyT, Ich habe noch nie von der Idee gehört, dass Referenzen Aliasnamen sind. Kannst du mir den Absatz des Standards angeben, wo dies enthalten ist? –