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.

+1


a source to share


4 answers


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.

+6


a source


The C ++ standard states that the compiler can choose to create a temporary object using the copy constructor, or it can choose to optimize the temporary.



There is a wikipedia article on this topic, with numerous links here .

+3


a source


The compiler is allowed to execute the copy on return. Most compilers won't. However, you must make sure you have a rnObj

copy constructor available.

+1


a source


Most modern compilers will be able to avoid creating a temporary object if optimization is enabled. See Named Return Value Optimization for details .

+1


a source







All Articles