汇编代码中的按引用/按指针
我想看看 C++ 中按引用调用与按指针调用有何不同。
但是,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
这里也没有区别..有没有一种简单的方法来触发语义重用?
I wanted to see how calling by-reference differs from by-pointer in C++.
However, the g++ compiler (using -O0 -S) produces identical code.
I tried 'tricking' the compiler in producing some sort of difference using all sorts of contrived constructs, but it seems more clever than I am.
Is there a way into turning off all cleverness in gcc so I can understand the implementation of references in assembly?
[Edit]
/* 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
No difference here either.. is there an easy way to trigger the semantic reuse?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
真的,没有什么需要理解的了。
引用是指针,和引用不是指针。
更准确地说,引用当然根本不是指针,它们是别名。这意味着从语义上讲,它们是相同的变量,只是名称不同。这意味着编译器通常可以采取巧妙的重命名技巧来完全优化引用的传递。
有时,它仍然必须以某种方式传递引用,然后这通常通过指针发生(这不是要求,但恰好是适合的一种技术)。与指针唯一可观察到的区别是,引用不能为空,并且编译器知道这一点(不过,如果你足够恶意,你可以创建一个空引用)。
There is not much more to understand, really.
Reference are pointers, and references are not pointers.
More correctly, references are of course not pointers at all, they are aliases. Which means that semantically, they are the same variable, just under a different name. This means that the compiler can often do clever renaming tricks to entirely optimize passing the references at all.
Sometimes, it still has to pass the reference somehow, and then that usually happens via a pointer (this is not a requirement, but happens to be the one technique that fits). The only observable difference to a pointer, under the hood, will be that a reference can't be null, and the compiler knows that (though, if you are malicious enough, you can create a null reference).
不,仅此而已。引用是其他地方存在的某个对象的另一个名称,即别名。
您现在已经了解到,在本例中,引用是使用它所引用的对象的地址(作为实现细节)来实现的。该语言没有说明它应该如何工作,只是说明效果是什么。
使用对象的地址似乎是一个简单的解决方案,当然实际上每个实现都使用它。
No, there is nothing more to it. The reference is another name, an alias, for some object that exists elsewhere.
You have now learned that the reference, in this case, is implemented using the address of the object it refers to (as an implementation detail). The language doesn't say how this should work, just what the effects are.
Using the object's address seems like a simple solution, and is of course what practically every implementation use.
显然不是。换句话说:您已经已经看到了:引用传递通常是通过指针实现的。
Apparently not. Put differently: you are already seeing it: pass by reference is usually implemented via pointers.
您应该考虑两个级别的语义 - C++ 和 ASM。
ASM 语义不包含引用,因此引用和指针被转换为指针(其他答案中已经提到过)。
然而,翻译规则可能存在差异。尝试玩一些类似的东西:
打破它的等价性。并尝试检查[ARM]以获取引用和指针的详细描述。我不确定我的回答是否对你有帮助,但希望如此。如果您发现反例,请反馈。我也有兴趣。
You should to consider two level of semantics - C++ and ASM.
ASM semantics doesn't contain references, so references and pointers are translated to pointers (it is already mentioned in other answers).
However probably there is a difference in translation rules. Try to play with something like:
to break its equivalence. And also try to check [ARM] for detailed description of references and pointers. I'm not sure if my answer will help you, but hope so. Please feed back if you find counterexample. I'm interested too.
这一切都与语义上下文有关!
引用是生成的二进制代码上下文中的指针。
参考文献仅是从 C++ 到 ASM 的转换阶段的参考文献。
C++ 标准没有告诉编译器编写者如何实现他们的编译器。但实际上,没有其他方便的方法在编译器中实现引用。
It's all about the semantic context!
References are pointers in the context of the generated binary code.
References are references only in the translation phase from C++ to ASM.
The C++ standard does not tell compiler writers how to implement their compilers. But practically, there is no other convenient way of implementing references in compilers.