0

I have the following method which returns the local declared Object by value:

Human Human::getLocalDeclaredHuman() {    
    Human human;
    std::cout << &human << std::endl;
    return human;
}

And I call this method:

Human a;
Human b = a.getLocalDeclaredHuman();
std::cout << &b << std::endl;
std::cout << b.getName() << std::endl;

and this is the output of the running program:
0x22fe58
0x22fe58
John Doe

So the variable human which is declared local in the method has the same address as the variable b. I thought return-by-value will create a copy of the object and that the object b has another address like the object human which is declared locally.

My question:
If here b and human have the same address, where is the difference between return-by-value and return-by-reference?

Jim Simson
  • 2,774
  • 3
  • 22
  • 30
Jan Koester
  • 1,178
  • 12
  • 26

5 Answers5

6

Return Value Optimization.

It isn't so much that the caller received a reference to the callee's local variable, but rather the compiler snuck a reference to the caller's variable into the callee!

getLocalDeclaredHuman.human never really existed. The compiler was able to optimize away its existence and do all of its work directly on b.

And, to answer your question directly, "where is the difference between return-by-value and return-by-refernce?": In this case, return-by-value means that the single object has the lifetime of b. If you were to return human by reference, that single object would have the lifetime of human, i.e. it would be destroyed when getLocalDeclaredHuman() returns.

Robᵩ
  • 163,533
  • 20
  • 239
  • 308
  • thanks for the link to get the background know-how and the nice explanation! – Jan Koester Feb 22 '12 at 17:51
  • 1
    And, just for bonus fun, consider what [this program](http://ideone.com/B2V9k) does. – Robᵩ Feb 22 '12 at 18:05
  • hehe, yeah. The c has another adress than the human in F2 because the compiler can not know what the condition i will be. It is possible that a new Human with a new adress is created. And that i1 in F1() and F2() hast the same adress is also tricky but the adress is free again when F1() finished, so i1 in F2() can take it – Jan Koester Feb 22 '12 at 18:25
1

That is because of return value optimization performed by your compiler.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
1

Most likely the copy is elided to the outside scope so that the only method being called is the default human copy constructor. Take a look at this question for more info.

Community
  • 1
  • 1
rerun
  • 25,014
  • 6
  • 48
  • 78
0

This is return value optimisation. The compiler knows what you're going to do with it so has created it at the location to where it will be assigned so it has no need to copy.

CashCow
  • 30,981
  • 5
  • 61
  • 92
0

Perhaps the compiler has optimized away the local variable, so that you're instead operating on b inside the function.

Like so:

void Human::getLocalDeclaredHuman(Human& returnValue)
{
  std::cout << &human << std::endl;
}

then this gets called on b, and thus prints b's address just like you're seeing. I believe this is the very definition of return value optimization.

unwind
  • 391,730
  • 64
  • 469
  • 606