引用如何在 gcc 中转换为 asm?
Posted
技术标签:
【中文标题】引用如何在 gcc 中转换为 asm?【英文标题】:How does reference translates to asm in gcc? 【发布时间】:2017-02-09 12:27:29 【问题描述】:引用是像通常的指针一样编译还是后面有其他东西?
clang 有什么不同?
【问题讨论】:
为什么不做一个简单的测试程序,用不同的编译器编译,看看生成的代码? 复杂情况下会有所不同 有时它甚至不需要存在于生成的代码中,因为编译器可以将其视为引用项的别名。 没有单一的固定方式,取决于具体情况和优化器。想一想,可能更准确的答案是,机器代码级别的引用不存在,所以没有必要问它是如何翻译成它的。引用是 C 级的东西,它可能是,编译的几个内部步骤可以识别为“引用”,但是当生成最终的机器代码时,不再需要这些信息,并且很可能丢失/损坏在编译 + 优化的最后一步中。 【参考方案1】:您可以将引用视为在使用时自动取消引用的不可变指针。这不是 C++ 标准所说的,所以你不能依赖它是一个实际的实现。
但实际上,在许多情况下,它可能就是您所看到的。 以传参为例:
#include <stdio.h>
void function (int *const n)
printf("%d",*n);
void function (int & n)
printf("%d",n);
int main()
int n = 123;
function(&n);
function(n);
gcc
和 clang
都为未启用任何优化的函数生成相同的代码:
function(int*):
push rbp
mov rbp, rsp
sub rsp, 16
mov QWORD PTR [rbp-8], rdi
mov rax, QWORD PTR [rbp-8]
mov eax, DWORD PTR [rax]
mov esi, eax
mov edi, OFFSET FLAT:.LC0
mov eax, 0
call printf
nop
leave
ret
function(int&):
push rbp
mov rbp, rsp
sub rsp, 16
mov QWORD PTR [rbp-8], rdi
mov rax, QWORD PTR [rbp-8]
mov eax, DWORD PTR [rax]
mov esi, eax
mov edi, OFFSET FLAT:.LC0
mov eax, 0
call printf
nop
leave
ret
【讨论】:
【参考方案2】:引用在 gcc 中是如何转换为 asm 的?
一般来说:视情况而定。
要在特定情况下找出这一点,您可以通过阅读生成的程序集进行测试。
引用是像通常的指针一样编译还是后面有其他东西?
使用引用的代码实现实际上与使用指针实现相同间接的代码实现相同。标准不保证每个是如何实现的,但没有必要以不同的方式实现它们。
引用与指针的区别仅在于 C++ 规则允许使用它们的方式。当然,因为规则不同,指针可以用引用不能的方式使用。在这种情况下,您无法比较指针是否生成相同的程序集。
引用的限制可能使一些优化更容易,所以可能会有差异,但这种优化也可以可能使用指针,所以没有使用引用而不是指针时保证不同的汇编输出。
clang 有什么不同?
一般来说:视情况而定。
两种编译器都受相同标准规则的约束。它们可能会生成相同的程序集或不同的程序集。一个编译器的特定版本生成的程序集与另一个编译器的特定版本生成的程序集有何不同(如果有的话),每个编译器都有特定的编译选项,在特定操作系统上的特定处理器架构上,在特定用例中可以通过检查和比较每种特定情况下生成的程序集来找到参考。
【讨论】:
以上是关于引用如何在 gcc 中转换为 asm?的主要内容,如果未能解决你的问题,请参考以下文章
您如何在运行时使用 GCC 和内联 asm 检测 CPU 架构类型?
如何从 C 中引用在 Visual Studio 的 .asm 文件中定义的全局变量