Is there a temporary creation when returning an object from a function?
when a function has an object passed by value, it uses either a copy constructor or a bit-wise copy to create a temporary stack space for use inside the function. How about any object returned by the function?
//just a sample code to support the qn
rnObj somefunction()
{
return rnObj();
}
and also explain how the return value is received by the called function.
a source to share
As you can tell from the other answers - the compiler can optimize this.
A concrete example created using MSVC to explain how this is possible (as asked in one of the comments) -
Let's take a class -
class AClass
{
public:
AClass( int Data1, int Data2, int Data3 );
int GetData1();
private:
int Data1;
int Data2;
int Data3;
};
With the following trivial implementation -
AClass::AClass( int Data1, int Data2, int Data3 )
{
this->Data1 = Data1;
this->Data2 = Data2;
this->Data3 = Data3;
}
int AClass::GetData1()
{
return Data1;
}
And the following calling code -
AClass Func( int Data1, int Data2, int Data3 )
{
return AClass( Data1, Data2, Data3 );
}
int main()
{
AClass TheClass = Func( 10, 20, 30 );
printf( "%d", TheClass.GetData1() );
}
(added printf () to make sure the compiler doesn't optimize everything) .... In unoptimized code, we expect Func () to create a local AClass on its stack, build it, and copy it as a return variable.
However, the generated assembly does look like (removing unnecessary lines) -
_TEXT SEGMENT
___$ReturnUdt$ = 8 ; size = 4
_Data1$ = 12 ; size = 4
_Data2$ = 16 ; size = 4
_Data3$ = 20 ; size = 4
mov eax, DWORD PTR _Data3$[esp-4]
mov ecx, DWORD PTR _Data2$[esp-4]
mov edx, DWORD PTR _Data1$[esp-4]
push esi
mov esi, DWORD PTR ___$ReturnUdt$[esp]
push eax
push ecx
push edx
mov ecx, esi
call ??0AClass@@QAE@HHH@Z ; AClass::AClass
mov eax, esi
pop esi
ret 0
The 3 function variables are popped off the stack and pushed into eax, ecx and edx.
Another fourth value is placed in esi (and passed to ecx).
The constructor is called with three parameters on the stack, and ecx still contains the fourth value.
Let's look at the constructor -
_TEXT SEGMENT
_Data1$ = 8 ; size = 4
_Data2$ = 12 ; size = 4
_Data3$ = 16 ; size = 4
mov edx, DWORD PTR _Data2$[esp-4]
mov eax, ecx
mov ecx, DWORD PTR _Data1$[esp-4]
mov DWORD PTR [eax], ecx
mov ecx, DWORD PTR _Data3$[esp-4]
mov DWORD PTR [eax+4], edx
mov DWORD PTR [eax+8], ecx
ret 12 ; 0000000cH
The parameters of constructor 3 are read into offsets eax-eax, which is a copy of ecx, the fourth parameter from the above call.
So the constructor builds the object where it is told - the fourth parameter is Func ().
And, you guessed it, the fourth parameter to Func () is actually the real only place in the entire program where the built AClass exists. Let's look at the relevant part of main () -
_TEXT SEGMENT
_TheClass$ = -12 ; size = 12
_main PROC
sub esp, 12
push 30
push 20
lea eax, DWORD PTR _TheClass$[esp+20]
push 10
push eax
call ?Func@@YA?AVAClass@@HHH@Z ; Func
12 bytes are reserved for AClass and three arguments are passed to Func (), plus a fourth to indicate those 12 bytes.
This is a specific example with a specific compiler. Other compilers do it differently. But this is the spirit of things.
a source to share
Most modern compilers will be able to avoid creating a temporary object if optimization is enabled. See Named Return Value Optimization for details .
a source to share