Bug 866 – Abstract classes can't have constructors: fails to link, hard to find problem

Status
RESOLVED
Resolution
INVALID
Severity
major
Priority
P2
Component
dmd
Product
D
Version
D1 (retired)
Platform
x86
OS
Windows
Creation time
2007-01-21T06:10:00Z
Last change time
2014-02-15T13:13:27Z
Keywords
diagnostic, link-failure, spec
Assigned to
bugzilla
Creator
matti.niemenmaa+dbugzilla

Comments

Comment #0 by matti.niemenmaa+dbugzilla — 2007-01-21T06:10:31Z
abstract class Parent { this(); } class Child : Parent { override this() {} } void main() { // both fail to link Parent p = new Child; Child c = new Child; } The above code fails to link, emitting "Symbol Undefined" errors referring to Parent._ctor. This ought to be caught by the compiler, as it's quite difficult to find the problem when you don't know what you're looking for. The override attribute of the constructor in Child is completely ignored: if Parent's constructor is removed, the code compiles and runs. I know that DMD ignores superfluous attributes, but this might be a good case to tag it as a n The fact that abstract classes can't have constructors is unmentioned in the spec (at least in attribute.html, where I would expect it to be stated), which is why I tagged this with "spec". Changing Parent to the following: class Parent { abstract this(); } The error "constructor asdf.Parent.this non-virtual functions cannot be abstract" is emitted. Changing Parent to an interface causes the error "constructor asdf.Parent.this special function not allowed in interface Parent", which is the kind of error I would expect for the abstract class as well. My ideal error messages would read: "interface cannot contain non-virtual function asdf.Parent.this" "abstract class cannot contain non-virtual function asdf.Parent.this" "non-virtual function asdf.Parent.this cannot be abstract"
Comment #1 by thomas-dloop — 2007-01-23T07:46:10Z
One more sniplet to demonstrate that DMD's current behaviour has undesired consequences: # class A{ # this(char[] foo){ # } # } # # abstract class B : A{ # this(char[] bar){ # } # } c.d(7): constructor c.B.this no match for implicit super() call in constructor
Comment #2 by bugzilla — 2007-01-31T14:53:08Z
For the first: The this(); declaration is not abstract, because it is not virtual. It is possible for abstract classes to have constructors. If the constructor is declared without a body, that means it is implemented elsewhere. It is important to allow this so one can 'hide' implementations from the user of the class. The error given is because there was no implementation found by the linker. Not a bug. For the second, the error has nothing to do with abstractness (the same error will happen without the abstract keyword). The error is caused by the B constructor has no call to A's constructor, so the compiler attempts to implicitly call super(). But there is no A.this(), hence the error message. Not a bug. For both cases, the compiler is working as designed.