1

I know there are a ton of questions asking something similar, but I couldn't find anything for my exact situation (operator overload, pass by copy).

As far as I know, returning a reference to a local variable and then using it should result in undefined behaviour. But it seems to be working in my case. Is it simply a case of undefined behaviour can also mean it will work sometimes, or am I overlooking something?

// complex.cc
    Complex& operator/(Complex lhs, const Complex& rhs)
    {
        return lhs /= rhs;
    }
// inside main
    complex::Complex a{3, -6};
    complex::Complex b{1, -5};
    complex::Complex res{a / b};
    std::cout << a << '\n' << b << '\n' << res << std::endl;

As I understand it, shouldn't there be a copy of a created, when I pass it to the overloaded operator, which then returns a reference to the modified copy? Is that understanding wrong, or why does it work when I print it?

neondrop
  • 121
  • 4
  • 11
    Bad luck. The behavior of the program is undefined. "Undefined behavior" doesn't mean "something bad will happen". It means that the C++ language definition doesn't tell you what the program does. – Pete Becker Jul 02 '23 at 20:31
  • Ok, thank you. I just wanted to be sure I didn't misunderstand anything there. – neondrop Jul 02 '23 at 20:33
  • 2
    If your compiler doesn't warn about it, increase the warning level. – Ted Lyngmo Jul 02 '23 at 20:43
  • @TedLyngmo Now that you mention it, that was part of why I was uncertain about this. I am using g++ with -Wall and no warning. – neondrop Jul 02 '23 at 20:46
  • @neondrop That's odd. How old is that g++? Which version? It seems to have warned for this ever since version 5.1. – Ted Lyngmo Jul 02 '23 at 20:48
  • @TedLyngmo g++ 12.2.0 Rev4 built my MSYS. I was using a makefile, but I just tried to compile it manually like this `g++ -Wall ComplexMain.cc complex\Complex.cc -o Complex.exe` still no warning. – neondrop Jul 02 '23 at 20:51
  • 2
    How strange. Does it help if you add `-Wextra` or if you specifically add `-Wreturn-local-addr` (which is usually enabled by `-Wall`)? **Edit**: Aha, now I see. Add `-O3` too and then it kicks in. – Ted Lyngmo Jul 02 '23 at 20:53

1 Answers1

4

But it seems to be working in my case. Is it simply a case of undefined behaviour can also mean it will work sometimes, or am I overlooking something?

You are not. The behavior is undefined, which means that it may look like it's working.

As I understand it, shouldn't there be a copy of a created, when I pass it to the overloaded operator, which then returns a reference to the modified copy?

That's also correct - and the copy goes out of scope when the function returns so the returned reference is a dangling reference.

Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
  • 1
    @neondrop `operator/` should return a new value, not a reference. `operator/=` should return a reference to the modified object. See [What are the basic rules and idioms for operator overloading?](https://stackoverflow.com/questions/4421706/) – Remy Lebeau Jul 02 '23 at 22:39