Is self-initialization 'A a = a;' allowed?
This code fails at runtime in the copy constructor.
But the compiler (MSVS2008) issues no warnings.
Could you explain (preferably cite the standard) whether this code is illegal or what?
I understand that A a = a; should never be written at the first place, but I am looking for a theoretical background.
class A
{
public:
A()
:p(new int)
{
}
A(const A& rv)
{
p = new int(*rv.p);
}
~A()
{
delete p;
}
private:
int *p;
};
int main()
{
A a = a;
}
Solution 1:
Your code is not calling the standard constructor but the copy constructor, so you are accessing an uninitialized pointer.
Solution 2:
Interesting reading on self-assignment: http://www.gotw.ca/gotw/011.htm
In particular, note "Postscript #1" in relation to this question and some of the answers given.
Solution 3:
According to the standard (12.6.1 [class.expl.init] ) self initialization is perfectly legal.
Therefore the following is legal.
A a = a;
You just need to write your copy constructor to deal with it correctly.
A(const A& rv)
{
if(&rv == this) {
p = new int(0);
return;
}
p = new int(*rv.p);
}
Edit: Updated code based on comments.
Solution 4:
A a = a;
definitely should not be written. But a = a
could be written. Your assignment operator must check for &rv == this
and do nothing in case of a self-copy.
Oh, yes, you do need to write an assignment operator for class A.