feeling_lonely
feeling_lonely

Reputation: 6883

Local varible (stack) returned as function return value

Here is an example for friend functions found on the internet:

#include <iostream>
using namespace std;

class Rectangle {
    int width, height;
  public:
    Rectangle() {}
    Rectangle(const Rectangle &r) { 
        width = r.width; 
        height = r.height;
        cout << "copy\n";
    }
    Rectangle (int x, int y) : width(x), height(y) {}
    int area() {return width * height;}
    friend Rectangle duplicate (const Rectangle&);
};

Rectangle duplicate (const Rectangle& param)
{
  Rectangle res;
  res.width = param.width*2;
  res.height = param.height*2;
  return res;
}

int main () {
  Rectangle foo;
  Rectangle bar (2,3);
  foo = duplicate (bar);
  cout << foo.area() << '\n';
  return 0;
}

Output:

24

Notice that the friend "duplicate" function creates a local variable and returns as return value to the caller. Isn't this supposed to be a local variable and is allocated on this stack? Should not it be destroyed once "duplicate" finishes execution? Is this example good?

Thanks.

Upvotes: 3

Views: 195

Answers (2)

Swift - Friday Pie
Swift - Friday Pie

Reputation: 14708

Your function return Rectangle by value , so it should be fine.

Rectangle duplicate (const Rectangle& param)

The returned object isn't located in same storage isn't same object as one declared by local variable from abstract level of language. De-facto, as Justin says, compiler may optimize out creation of temporal object.

You would be in red, if you declared

Rectangle& duplicate (const Rectangle& param)

then function would try to return a reference to local variable.

How code is written, it is an equivalent of expression.

return Rectangle(param.width*2, param.height*2);

Copy constructor:

Rectangle(const Rectangle &r) { 
    width = r.width; 
    height = r.height;
}

should be proprly written as

Rectangle(const Rectangle &r): width(r.width), height(r.height) 
{ 
}

The ouput line is a side-effect that might be omitted due copy elision.

Upvotes: 3

iBug
iBug

Reputation: 37317

Just think of regular types:

int getInt(void) {
    int a = 5:
    return a;
}

The function does not really return the local variable a. Instead it returns a copy of a. Similarly, res is not returned by the function, but its copy.

In practice, the compiler is likely to detect your function and optimize the function by avoiding copying Rectangle.

To observe the constructor calls, compile it with

g++ -fno-elide-constructors foo.cpp -o foo

You must disable return value optimization for g++ (-fno-elide-constructors), which is a very basic optimization that'll be turned on even with -O0.

Upvotes: 10

Related Questions