I read in Computer Systems a programmer perspective that when one is programming in assembly code, the convention regarding the caller-callee protocol states that the returned value of a function should be stored in the eax
(or the analogue rax
, in the 64-bit computer) register.
I'm guessing this is what automatically happens "behind the scenes" when programming in C, meaning the C compiler "knows" to use the eax
register for functions returned values.
But what happens in C++, when the returned value is a big object that doesn't fit into the 32-bit eax
or 64-bit rax
register? Obviously you can't pass this using the stack, so how does the compiler handle a return-by-value operation of a big object?
Never mind a big object, how does the C compiler handle a return-by-value of a big structure?
Does it save it in a temporary memory space and returns its address as a return value? If so, it has to predict how many calls are to be done to the function during runtime, and sometimes it is impossible, isn't it?
A structure can be returned from a function using the return keyword. Structures can be passed into functions either by reference or by value. An array of structures can also be passed to a function.
Q: How are structure passing and returning implemented? A: When structures are passed as arguments to functions, the entire structure is typically pushed on the stack, using as many words as are required. (Programmers often choose to use pointers to structures instead, precisely to avoid this overhead.)
One of them asked if you could return a struct from a function, to which I replied: "No! You'd return pointers to dynamically malloc ed struct s instead."
Return struct from a functionThe function returns a structure of type struct student . The returned structure is displayed from the main() function. Notice that, the return type of getInformation() is also struct student .
Obviously you can't pass this using the stack...
Actually, the theory is that whenever a function is called and its stack frame is accommodated, it also makes room for the return object. It is then up to the calling function to ensure that that return value is copied somewhere within its own stack frame so that it can hold on to it.
This directly corresponds to how it works in C and C++. You have a return ...;
statement, which copies some value into the return object. The return object is a temporary object, so the calling code has to store it somewhere, with something like int value = foo();
.
However, it is pretty much never necessary to even bother with reserving space for the return value. Instead, the calling function makes room for it and the called function places the return value directly there. That's exactly what return value optimization is and what copy elision represents.
Obviously you can't pass this using the stack
You can! The trick is to have the caller allocate the space on the stack, and let the function fill it in.
Essentially, the function returns the data in the caller's portion of the stack frame.
You should imagine that the return value of a function goes onto the stack, like a local variable. And, like local variables, this can be optimized (and there are conventions depending on the architecture which dictate a well defined behavior) so that small return values go into registers instead of stack.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With