0

As known, returning local variable from function in C++, is unsafe, due to scoping. In Effective C++ Third Edition, Scott Meyers tells about this problem in item 21, at page 101. However, in conclusion he said, that right decision will be to write:

inline const Rational operator*(const Rational& lhs, const Rational& rhs) {
    return Rational(lhs.n * rhs.h, lhs.d * rhs.d);
}

Isn't this also a bad practice, and this function is unsafe?

Braiam
  • 1
  • 11
  • 47
  • 78
  • 1
    C++ has value semantics. To understand why what you're thinking of is bad, read http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope. – chris Jul 16 '14 at 20:25
  • 3
    Returning pointer or reference to local variable is unsafe, returning variable by value is absolutely legal – Slava Jul 16 '14 at 20:28
  • For reference, Item 21 in Effective C++ (3rd edition) states: "*Don’t try to return a reference when you must return an object.*" – Austin Moore Jul 16 '14 at 20:37
  • What does "unsafe" mean? – Kerrek SB Jul 16 '14 at 20:37
  • In the mentioned item you'd find the response: "and it turns out that in some cases, construction and destruction of operator*’s return value can be safely eliminated". So no pressure on try to optimize something compiler vendors should give you for free. – fiorentinoing Feb 22 '18 at 14:00

4 Answers4

8

Returning local variable from a function is normal and nothing wrong. Returning pointer or reference to a local variable is different story, but in your example there is nothing of the sort.

Praetorian
  • 106,671
  • 19
  • 240
  • 328
Wojtek Surowka
  • 20,535
  • 4
  • 44
  • 51
7

You can't actually return a local variable. You can return the value of a local variable, or a pointer to it (i.e., its address), or a reference to it.

Returning the value of a local variable is perfectly safe:

int good_func() {
    int local = 42;
    return local; // returns a copy of the value of "local"
}

Returning a pointer or reference to a local variable is unsafe, because the variable ceases to exist when the function terminates:

int* bad_func() {
    int local = 42;
    return &local; // returns a pointer to "local"
}

(The same applies in C, except that C doesn't have C++-style references.)

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
2

No, this is not unsafe, because Rational is returned by value. This means that the caller gets a copy of the Rational that you create, which makes the whole process safe.

It is unsafe to return a reference to a local variable, or to access through a reference an object that has gone out of scope. This is not what is happening in the code example, though.

Note that the copy may be created without copying, which has a potential of degrading performance. This is because C++ compilers can use return value optimization technique described here.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
0

No it's not unsafe, you are returning by value, even in C++98 it's safe, but in C++98 possibly will no be fast enough because of the additional unnecessary copy (using Move Semantic in C++11 avoid the copy). Nevertheless it's not recommended for big object by many of the C++ gurus. The problem with big objects is that move might decay into copy in some of the data members of the object.

NetVipeC
  • 4,402
  • 1
  • 17
  • 19
  • Even in C++98, RVO is sure to take care of this. – chris Jul 16 '14 at 20:30
  • That's not necessarily true. In c++98 there was [return value optimizations](http://stackoverflow.com/questions/12953127/what-are-copy-elision-and-return-value-optimization) – Bill Lynch Jul 16 '14 at 20:30
  • Not quite true, RVO was available in C++98 – Slava Jul 16 '14 at 20:30
  • Yes RVO and NRVO is a fantastic improvement, but in some corner cases optimization no apply (even with cases that depending the compiler used, may o may not apply), in performance sensitive code some time is necessary to be sure that no copy would be performed. – NetVipeC Jul 16 '14 at 20:53