I know using self assignment of objects is not a good idea and obviously no one ever explicitly does a self assignment like this.
MyClass obj;
obj = obj;
Is there any reason why C++ supports this or is there any particular situation to use this?
In addition to the answers already posted by Carl Norum and Ralph Tandetzky ask yourself whether a compiler can detect all possible self-assignments.
The answer should be obvious, that no, it cannot. Consider this rather simple (and silly) snippet of code:
Class obj1;
Class obj2;
Class *ptr = &obj1;
if((rand() % 7) == 0)
ptr = &obj2;
obj2 = *ptr;
This code will sometimes result in self-assignment. Should the compiler warn you? With what? "Heisenberg Error #3: Self-assignment when rand()
returns a multiple of 7?" What if your rand
only returns numbers in the range [0, 6]?
And this is a simple example that a compiler could fairly easily figure out. There are more convoluted snippets of code that would be a lot more difficult to catch, but could be caught if the compiler performed extensive flow analysis of the code but then it would take much longer to run. And, of course, there are very convoluted snippets of code that can exhibit this behavior that are very hard or even impossible to catch.
So, you could have a compiler that took much longer to run only to sometimes probabilistically warn you about a potential self-assignment. Frankly, that's worse than not warning.
If you feel that this is a problem and you don't want to allow it, then having a coding standard that says "no self-assignments!" is probably the better idea.
Sidenote: There are tools that can do a lot of very sophisticated source code analysis to try and root out issues; such tools can be configured to and will catch many such self-assignments, including some convoluted ones. But they still don't catch everything, take a while to run and typically cost in the thousands of dollars.
I guess there's no reason to prohibit it. Why would you? To create an extra language rule? As far as I know there is no real use of self assignment.
There are good reasons to allow an object on both sides of an assignment, for example
obj = f( obj );
The line
obj = obj;
is really just a special case of that.
I think its just possible to do. Like you can move the value of the same register itself in assembly:
mov eax, eax
It just fits into design that's made universal.
It's probably allowed because there's no real reason to disallow it. I've seen it used as a workaround for unused variable warnings, though I wouldn't recommend that usage personally.
For POD objects or objects without a constructor, it can be used to suppress "may be used before initialized
" warnings (if a declared local variable is really unused, it should just be removed).
When at file or namespace scope, it can be used as a hack to prevent initialization of a global object that is being used by constructors of other global objects.
std::list<Foo> g_foos;
If a static instance of Foo
added itself to g_foos
before g_foos::g_foos()
gets to run, then the list would empty itself out, and the registration would be lost. A self initialization prevents that.
std::list<Foo> g_foos = g_foos;
But there are better ways to implement a global instance that also prevent this problem, for instance:
std::list<Foo> & the_foos () {
static std::list<Foo> foos;
return foos;
}