Reputation: 61
Why does the assignment operator is allowed to return void? And why does assignment chaining works in this case? Take a look at the code, it will be very clear what am I talking about.
Code:
struct Foo
{
std::string str;
Foo(const std::string& _str)
: str(_str)
{
}
Foo& operator=(const Foo& _foo)
{
str = _foo.str;
//return *this; /* NO RETURN! */
}
};
int main()
{
Foo f1("1");
Foo f2("2");
Foo f3("3");
f1 = f2 = f3 = Foo("4");
std::cout << "f1: " << f1.str << std::endl;
std::cout << "f2: " << f2.str << std::endl;
std::cout << "f3: " << f3.str << std::endl;
return 0;
}
Questions:
I've read in many places "assignment operator should return *this so that you can have assignment chaining" which totally makes sense, but then why does the above work?
Try it out:
online c++ workspace with the code from above
Upvotes: 5
Views: 2121
Reputation: 1197
It's illegal and if it compiles, then in some way it is storing something weird for the runtime. And you must return *this
from the function. The correct function definition will look like:
Foo& operator=(const Foo& _foo)
{
if(this == &_foo) /* check for self-assignment */
return *this;
str = _foo.str;
return *this;
}
Returning *this
is a must for chain assignments like:
Foo x, y, z;
x = y = z; /* *this is necessary for this statement */
Upvotes: 0
Reputation: 11
Check what asm code is produced after compiling. My guess is that this function returns what happens to be in register AX (this is c-call standard function implementation if I'm not mistaken). In your case, it happens to be what you are wanting it to be... if you add some functionality to function you might break it...
Upvotes: 0
Reputation: 126432
Why is this legal? (why does it compile at all)
This is not legal, and injects Undefined Behavior in your program. Your compiler should at least warn you about that (and I believe it does, if you set a sufficiently high warning level).
Per Paragraph 6.6.3/2 of the C++11 Standard:
Flowing off the end of a function is equivalent to a return with no value; this results in undefined behavior in a value-returning function.
The only exception is the main()
function, which is allowed to have a missing return
statement. Per Paragraph 3.6.1/5:
A return statement in
main
has the effect of leaving themain
function (destroying any objects with automatic storage duration) and callingstd::exit
with the return value as the argument. If control reaches the end ofmain
without encountering a return statement, the effect is that of executingreturn 0;
Finally:
Why does it work?
Undefined Behavior means that your program may run on some machines but not on others; or it may run on all machines today, but not tomorrow; or it will cause your program to have some bizarre, unpredictable outcome; including (which is the worst case) seeming to run perfectly fine.
Upvotes: 8
Reputation: 227420
What you have is undefined behaviour, because you are flowing off the end of a function that promises to return something.
The only function for which it is legal to do this in C++ is int main()
(and version with arguments), because it implicitly returns 0
in the absence of a return statement.
Upvotes: 2