When call by value is used, actual parameter values are pushed into the stack. What about call by reference开发者_JS百科? What is pushed onto the call stack?
EDIT:
Nice to know that java does not use call by reference, ever. How about in C++. I changed the tag to c++ from java. Sorry for the confusion.
There is no call by reference in Java. Everything is call by value.
From Is Java "pass-by-reference" or "pass-by-value"?
Java is always pass-by-value. The difficult thing can be to understand that Java passes objects as references passed by value.
From http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html
Java does manipulate objects by reference, and all object variables are references. However, Java doesn't pass method arguments by reference; it passes them by value.
See this answer for further explanation.
What about call by reference? What is pushed onto the call stack?
Then the reference is pushed onto the operand stack.
What do you mean "when call by value is used"? Java is always call by value, except most of the values are object references. But there's no "if" or "when", it always works the same.
So yes, at the bytecode level the references themselves are pushed onto the stack. What these are comprised of is up to the JVM implementation (I think), but it's almost certain that they're memory addresses.
In C++ the address of the variable is pushed onto the stack when call be reference is used. Due to this a new object creation will be eliminated, and whatever changes you do in the callee function will be available in the caller.
It depends on the C++ implementation. Maybe references are just passed as pointers. Maybe they're put in registers instead of the stack. Maybe a stack doesn't even exist. The C++ language doesn't mandate any of these things.
Additionally, how things are passed (a.k.a. the "calling convention") can be different within the same implementation. For example, if a function is inlined, the referents could just be used directly instead of through the above possibilities. Many implementations provide extensions that allow you to specify the calling convention (such as __fastcall
on Windows).
The reference is a "Special pointer". It is the address of a phisical object. The important difference between reference and pointer are two:
1) the reference cannot be null and MUST always pointing to a existing object.
2) You cannot reassign a reference to another object.
Also the reference and object are using the same syntax "." instead of "->".
The reference are very good because you can avoid to create a temporary object (for example in a function call).
back to your question: What is pushed onto the call stack?
The address of the object pointed by the reference.
It could be compiler dependent, but g++ puts the address of the variable on the stack. This is shown by making a disassembly of the code:
void func_by_ref(int& i) {
i = 2;
}
(gdb) disas func_by_ref
Dump of assembler code for function _Z11func_by_refRi:
0x080486b0 <+0>: push %ebp
0x080486b1 <+1>: mov %esp,%ebp
0x080486b3 <+3>: mov 0x8(%ebp),%eax
0x080486b6 <+6>: movl $0x2,(%eax)
0x080486bc <+12>: pop %ebp
0x080486bd <+13>: ret
End of assembler dump.
This is identical to code generated when using a pointer parameter, like
void func_by_pointer(int* i) {
*i = 2;
}
精彩评论