I'm looking a lot more closely at referenes now, and I would like to know if there is a tutorial on them. Why would you not return a reference whenever you return an object? Thanks!
This is a discussion on References within the C++ Programming forums, part of the General Programming Boards category; I'm looking a lot more closely at referenes now, and I would like to know if there is a tutorial ...
I'm looking a lot more closely at referenes now, and I would like to know if there is a tutorial on them. Why would you not return a reference whenever you return an object? Thanks!
Do not make direct eye contact with me.
You wouldn't want to return a reference to an object on your stack.
gg
Your object would be destroyed within the function once the function completes. Unless of course its a static object.
Duh, duh. What about functions that are always going to be used like this:
var = rFunc();
? Thanks again!
Do not make direct eye contact with me.
rFunc() can return a reference if it wants to - just make sure the memory that belongs to that reference is still valid after rFunc() returns.
So you wouldn't want to return something off of rFunc()'s stack since that memory isn't valid once rFunc() returns.
gg
Your saying to make sure that the variable the reference is "aiming at" hasn't been destroyed? I suppose that makes sense.
Do not make direct eye contact with me.
Correct. Do not use references for variables that are on the function's local stack.
When you enter a function C sets up a stack. If you have parameters those are popped off of the stack and used. If you declare a variable inside of the function and attempt to return a reference to that variable, you will have major problems
This is ok because the value of i is returned, not the address of i.Code:int MyFunc(void) { int i=0; return i; }
What MyFunc might look like in assembly (NASM):
So if you were to return a reference to i, it no longer exists. But if you return the value of i, the compiler moves the value at [esp-4] or where 'i' is into eax - in C all integral returns are returned in EAX and all floating point return values are in ST(0).Code:MyFunc: push ebp //save base pointer mov esp,ebp //set stack pointer to base sub esp,4 //subtract 4 for int -> int i=0; mov [esp-4],0 //set i to 0, i is at esp-4 mov eax,[esp-4] //mov value of 0 to esp-4 or i to return value to C add esp,4 //Erase i by adding 4 to stack pointer pop ebp //Restore base pointer ret //return to caller
So you see the add esp,4 and pop ebp effectively erase i and its address. It no longer exists. Future functions will use the stack and alter what we called 'i'.
Stack on entry to MyFunc
---------------> top of stack on entry
previous value of EBP
caller address
function parameters
Then when we declare integer 'i' which takes 4 bytes in 32-bit code - we reserve 4 bytes above the current stack pointer for this:
Stack after declaring variable 'i'
[esp-4] 'i' -----> 4 bytes above the top of the stack
-----------------> top of stack on entry
previous value of EBP
caller address
function parameters
....
....
And this on exit from MyFunc (after the parameters are popped off of the stack or removed):
Stack on exit from MyFunc
(previous position of variable i)
----------------> top of stack on exit
previous value of EBP
caller address
(parameters -> are popped off before returning to caller)
So if you return a reference to where i was, you will have major issues in your code because 'i' does not exist anymore.
Also you will note that the pop ebp will pop the first or top item off of the stack which just happens to be the previous address of EBP - so EBP is restored to what it was on entry. Then the RET will return to the caller - essentially - the actual nitty gritty of the RET instruction takes about 3 pages in the Intel manuals.
Last edited by VirtualAce; 12-23-2003 at 12:25 AM.
Got it, thanks for the VERY extended explanation. I don't know NASM, but I do understand in a psudocode sense, thanks all
.
Do not make direct eye contact with me.