Why does the following compile ??
class A{
A(){
A* a = new A() ;
}
} ;
Shouldn't it fail for the same reason something like fails ?
class A{
A obj;
} ;
class A{
A obj;
} ;
is a recursive bomb because A
's size is based on A
. Obviously that can't be allowed. A
doesn't know how big A
is and never will. This is easy to catch at compile time.
class A{
A(){
A* a = new A() ;
}
} ;
Is still a recursive bomb, but it will blow up at run time, making it a logical error and not a syntax error. The compiler may emit a warning.
The secret here is that functions defined in a class are, through the magic of inlined functions ([dcl.fct.spec] point 3, but is seems to be point 4 under [dcl.inline] in more recent drafts of the standard), and compiled after the class is defined when it is used in other code (or not at all, as M.M points out below, if the function is never used).
Since the function will be moved outside of the class definition before it is compiled, the size of A
is known at the time the function is compiled so it can be constructed safely.
As for A* a
, that's just a pointer. The size is baked right in and has no special requirements.
The declaration
class A{
A obj;
} ;
is illegal because you declare an infinite storage this way. Note, that containing a static field of own class or non-static of base class is legal though.
class A {
public:
static A a;
};
A A::a = A();
class B : A {
A obj;
}
Things like
class A{
A(){
A* a = new A();
}
};
are possible, whatever is declared inside method is a different storage. It is legal by the language rules but semantically it is wrong, a call to such constructor would cause an infinite recursion.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With