Bug 12737 – static constructor requires call of super constructor

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-05-12T15:43:00Z
Last change time
2014-05-13T07:55:44Z
Assigned to
nobody
Creator
rburners

Comments

Comment #0 by rburners — 2014-05-12T15:43:05Z
class A { this(int a) { } } class B : A { static this() { } } void main() { auto n = new B(); } fails to compile with: Error: class staticctor.B Cannot implicitly generate a default ctor when base class staticctor.A is missing a default ctor IMO that is wrong. A has no static ctor nor static members.
Comment #1 by issues.dlang — 2014-05-12T19:59:08Z
No, this isn't a bug in the compiler, and it doesn't have anything to do with static constructors. It's a bug in your code. This would fail to compile with the same error: class A { this(int a) { } } class B : A { } void main() { auto n = new B(); } The problem is that B's constructor must call A's constructor, but a compiler-generated default constructor (which is all B is going to have, because you didn't declare one for it) can only call default constructors for its base class, and A doesn't have one. It has a constructor which takes an int. So, you have to either add a default constructor to A or add an explicit default constructor to B which calls A's constructor with an int of whatever value would be appropriate.
Comment #2 by rburners — 2014-05-12T20:35:39Z
But it is the static ctor and A has no static member!?
Comment #3 by issues.dlang — 2014-05-12T20:50:28Z
The static constructor has nothing to do with the error. Look at my counter-example. It's exactly the same except for the fact that it has not static constructor. The problem is that a constructor for B must call A's constructor, e.g. class B : A { this() { super(42); } } but you didn't declare one, and the one created by the compiler looks like class B : A { this() { super(); } } but A doesn't have a default constructor, so that doesn't work, and so the compiler gives you the error that it's giving you. It's telling you that you need to either give A a default-constructor so that B's compiler-generated default constructor will work, or you need to declare a default constructor for B which calls the constructor that A does have. static constructors have nothing to do with inheritance and will work just fine regardless of whether a class has static members (it just won't have much to do if the class doesn't have any static members). So, if the static constructor in B were complaining about the lack of one in A, then yes, that would be a bug in the compiler. But that's not what's happening. The compiler is complaining about the fact that it can't generate a valid default constructor for B due to the lack of a default constructor in A. This code would compile just fine class A { this(int a) { } } class B : A { static this() { } this() { super(42); } } void main() { auto n = new B(); } as would this code class A { this(int a) { } this() { } } class B : A { static this() { } } void main() { auto n = new B(); }
Comment #4 by rburners — 2014-05-13T07:54:02Z
I was stupid here the problem occurs when class A { this(int a) { } } class B : A { static @trusted this() { } this() { super(1); } } void main() { auto n = new B(); } Error: constructor staticctor.B.this no match for implicit super() call in constructor
Comment #5 by rburners — 2014-05-13T07:55:44Z
it works if I put the trusted first ...