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