Operator overloading and scope

It might be because it's Monday but... As I was reading up on some operator overloading I saw multiple things like here. But is it just me or will the object 'box' in operator+ go out of scope after the addition? So returning the object isn't valid?

When a function returns an object, does it return a copy of the local variable (just like a function returning an int, char, or float)? If so, then it would be OK.

"box" in the operator overloader will be assigned/copied to "Box3" before it goes out of scope. If Box3 would have been a pointer reference to "box", there would have been a problem :slight_smile:

Is it really copied to Box3? I was under the impression 'Box3' was just pointed to the same instance as 'box'. But if indeed the whole object is copied to 'Box3' or another placeholder it's indeed fine.

Damn, my C++ is getting rusty :confused:

Box operator+(const Box& b) {

Copy is returned. (no & nor * for the return value)

   Box3 = Box1 + Box2;

Requires two copies. One for the addition. One for the assignment.

I believe a reference could be used to avoid the assignment copy...

  Box & Box3 = Box1 + Box2;

If I remember correctly, adding a simple constructor will knock the whole thing off the rails (no copy constructor; the compiler would be synthesizing one with the code presented). Explicitly defining a copy constructor probably would have reduced / eliminated your confusion.

septillion:
Is it really copied to Box3? I was under the impression 'Box3' was just pointed to the same instance as 'box'. But if indeed the whole object is copied to 'Box3' or another placeholder it's indeed fine.

Damn, my C++ is getting rusty :confused:

To be honest, I'm not 100% sure. Since "box" goes out of scope after the assignment and since Box3 has it's own place in memory, the values in "box"'s memory must be copied to the memory of "Box3" if it should make any sense. If Box3 would just be pointed to "box", subsequent calls to the operator would invalidate "Box3", let alone all the memory fragmentation this would cause since a new instance of "Box" must be constructed for each use of the operator.

Correct me if I'm wrong! :slight_smile:

Well, it is extremely difficult to build an example with a recent Arduino IDE. The optimizer is essentially eliminating everything. The example from the link is reduced to just prints (no Box; no math; nothing).

A for-loop with a call to setLength reduces to a single floating-pointing addition performed in place.

Oh well. You will just have to take my word for it. :slight_smile: (But, as the Alzheimer's president used to say, "Доверяй, но проверяй.")

@Coding Badly, true. But when passing arrays you don't see the & or * either. And I was under the impression it was along the same lines.

[quote author=Coding Badly date=1521472678 link=msg=3654688]

   Box3 = Box1 + Box2;

Requires two copies. One for the addition. One for the assignment.[/quote]
Makes sense although wouldn't the compiler be smart enough to do it at the same location?

Doesn't that only allocated memory for a pointer (although reference) and become out of scope after the addition finishes?

Maybe, because thinking along the lines of arrays I couldn't figure out how a copy / assignment / addition would otherwise work / should be looking like.

Thanks all!

In general, it's ok to return a instance/structure, because it isn't really local memory. The returned object is really a "secret argument" passed in by the caller. The called routine fills out this instance and "returns" it (not really). At the assembly level, it looks more like a void function with an extra parameter. After returning, the caller then uses the local instance to use the "returned" value.

Not only that, the compiler is free to eliminate copy operations where possible. This is called copy "elision". Some nice examples here.

The compiler is pretty good about catching cases where returning a reference to a local variable is dangerous.

septillion:
@Coding Badly, true. But when passing arrays you don't see the & or * either. And I was under the impression it was along the same lines.

No. Arrays and functions are unique (the name is a reference).

Makes sense although wouldn't the compiler be smart enough to do it at the same location?

Possibly. I've seen a hidden pointer used. (see -dev's post above) That's efficient.

For small structures I have seen registers used. That's efficient.

I vaguely recall an old C compiler padding the stack with enough space for the returned structure. That's functionally equivalent to a hidden pointer but far less efficient.

Doesn't that only allocated memory for a pointer (although reference) and become out of scope after the addition finishes?

It would be a reference to an anonymous instance of Box. The anonymous instance would reside on main's stack frame in your example and have the same lifetime / scope as Box3.