我想看看by-reference与C ++中的by-pointer的区别
但是,g ++编译器(使用-O0 -S)生成相同的代码
我试图“欺骗”编译器使用各种各样的设计构造产生某种差异,但它似乎比我更聪明。
有没有办法关闭gcc中的所有聪明才能让我能理解汇编中引用的实现?
[编辑]
/* Testing assembly representation of ref/pointer/by-value parameters */
int byRef(int &value, int value2) {
value = value2;
return value;
}
int byPtr(int * value, int value2) {
*value = value2;
return *value;
}
int main(int argc, char * argv[]) {
int value = 5;
byRef(value, value);
byPtr(&value, value);
}
call ___main
movl $5, -4(%ebp)
movl -4(%ebp), %eax
movl %eax, 4(%esp)
leal -4(%ebp), %eax
movl %eax, (%esp)
call __Z5byRefRii
movl -4(%ebp), %eax
movl %eax, 4(%esp)
leal -4(%ebp), %eax
movl %eax, (%esp)
call __Z5byPtrPii
movl $0, %eax
这里没有区别..是否有一种简单的方法来触发语义重用?
答案 0 :(得分:5)
真的没有太多要理解的了。
引用是指针,和引用不是指针。
更准确地说,引用当然是根本不是指针,它们是别名。这意味着在语义上,它们是相同的变量,只是在不同的名称下。这意味着编译器通常可以使用巧妙的重命名技巧来完全优化传递引用。
有时,仍然必须以某种方式传递引用,然后通常通过指针发生(这不是一个要求,但碰巧是适合的一种技术)。对于指针的唯一可观察的区别是,引用不能为null,并且编译器知道(但是,如果你足够恶意,你可以创建一个空引用)。
答案 1 :(得分:3)
不,没有更多的东西了。引用是另一个名称,别名,用于其他地方存在的某个对象。
您现在已经了解到,在这种情况下,引用是使用它引用的对象的地址实现的(作为实现细节)。该语言没有说明这应该如何工作,只是效果是什么。
使用对象的地址似乎是一个简单的解决方案,当然实际上每个实现都使用。
答案 2 :(得分:2)
有没有办法关闭gcc中的所有聪明才能让我理解汇编中引用的实现?
显然不是。换句话说: 已经看到了它:通过引用传递通常是通过指针实现的。
答案 3 :(得分:2)
所有关于语义的背景!
引用是生成的二进制代码上下文中的指针。
引用仅在从C ++到ASM的转换阶段引用。
C ++标准没有告诉编译器编写者如何实现他们的编译器。但实际上,没有其他方便的方法可以在编译器中实现引用。
答案 4 :(得分:1)
您应该考虑两个级别的语义 - C ++和ASM。 ASM语义不包含引用,因此引用和指针被转换为指针(在其他答案中已经提到过)。
然而,翻译规则可能存在差异。尝试使用类似的东西:
int i = 7;
int * pi = i;
int & ri = i;
int &* rpi = pi;
int *& pri = &ri;
打破它的等价。并尝试检查[ARM]以获取引用和指针的详细说明。我不确定我的回答是否会对你有所帮助,但希望如此。如果您发现反例,请反馈。我也很感兴趣。