By-reference / by-pointer in assembly code
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(%eb开发者_开发知识库p), %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?
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.
Is there a way into turning off all cleverness in gcc so I can understand the implementation of references in assembly?
Apparently not. Put differently: you are already seeing it: pass by reference is usually implemented via pointers.
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:
int i = 7;
int * pi = i;
int & ri = i;
int &* rpi = pi;
int *& pri = &ri;
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.
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.
精彩评论