Home How is a local variable created in functions?
Reply: 3

How is a local variable created in functions?

Martin
1#
Martin Published in 2018-02-12 20:36:29Z

Lets say I have this code:

#include <iostream>
using namespace std;

class A{
public:
    A() { cout << "In normal ctor\n"; }
    A(const A& a) { cout << "In cpy ctor\n";  }
    A(A&& a) { cout << "In move ctor\n"; }
    ~A() { cout << "In dtor\n"; }
};

A func(A a) {
    return a;
}

void main(){
    A a1;
    A a2 = func(a1);
}

The output is the following:

In normal ctor
In cpy ctor
In move ctor
In dtor
In dtor
In dtor

Now I'm having trouble understanding what's happening inside the function ''func''.

When a1 is sent to the function, the function doesn't receive it byRef,but rather it ''creates'' it's own version of a1 which is 'a'.

That's why when the function ends, the object ''dies'' and it goes the the destractor.

So why doesn't it also go to the constructer in the first place? (Assuming that a local object is really created there)

Is there any copying that's happening behind the scenes?

Thanks in advance!

dasblinkenlight
2#
dasblinkenlight Reply to 2018-02-12 20:52:18Z

Here is what happens (your program's printouts with explanations):

  • In normal ctor - This happens in A a1; of main
  • In cpy ctor - This happens when A a of func get initialized from a1 of main
  • In move ctor - This happens when a of func, a copy of a1, gets set into a2 (see copy elision in return)
  • In dtor - a1's copy is destroyed
  • In dtor - a2 is destroyed
  • In dtor - a1 is destroyed

I think the key thing here is to understand the role of the move constructor in creating a2. Your func returns A by value, which should get copied into a2. However, C++ compiler realizes that your program has no way of using the original value after the assignment, so it optimizes the call by invoking the move constructor.

AdityaG
3#
AdityaG Reply to 2018-02-12 20:44:59Z
void main(){
    A a1; -- > Normal constructor
    A a2 = func(a1); --> Copy(a1 to a), Move(a to a2), destructor(a)
} -->  destructor a1, a2

That is the reason you are seeing the output in that order.

Garrett Gutierrez
4#
Garrett Gutierrez Reply to 2018-02-12 20:45:37Z

func is passed an A by copy (I.E. there is no reference and it isn't a pointer, etc.). That is why the copy constructor is called. After it is created it is moved into the position of a2, thus the move constructor. After the move, a is destroyed (because func returns and it is out of scope), and then both of a1 and a2 (because main returns).

You asked why it doesn't go into the constructor but it does. For every A you create a different constructor is called, first a1 (normally) then a in func (via copy) and then finally a2 (via move).

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.363933 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO