Comment #0 by bearophile_hugs — 2010-07-26T13:35:11Z
A problem found by Jesse Phillips. This is Java program:
class Base {}
class Derived extends Base {}
abstract class Abstract {
abstract Base foo();
}
class Concrete extends Abstract {
@Override Derived foo() {
return new Base();
}
}
class Test {}
The javac compiler prints:
Test.java:11: incompatible types
return new Base();
^
required: Derived
found: Base
1 error
But dmd 2.047 compiles this D2 program with no errors:
class Base {}
class Derived : Base {}
abstract class Abstract {
abstract Base foo();
}
class Concrete : Abstract {
override Derived foo() {
return new Base;
}
}
void main() {}
Comment #1 by michal.minich — 2010-12-09T01:16:45Z
Slightly extended example shows that the returned instance is of type derived!, but constructor is not called.
class Base {}
class Derived : Base { this () { x = 1; } int x; }
abstract class Abstract {
abstract Base foo();
}
class Concrete : Abstract {
override Derived foo() {
return new Base;
}
}
void main() {
auto c = new Concrete;
auto x = c.foo();
writeln (typeof(x).stringof); // prints Derived (even it is result of 'new Base')
writeln (x.x); // prints 0 (wich means Derived's constructor is not called)
x.x = 2;
writeln (x.x); // prints 2
}
Comment #2 by dfj1esp02 — 2010-12-09T11:27:03Z
> auto c = new Concrete;
> auto x = c.foo();
> writeln (typeof(x).stringof); // prints Derived (even it is result of 'new
> Base')
You're doing it wrong.
typeof(x) is evaluated at compile time and always gives the declared type even if x==null
The correct code is
---
auto c = new Concrete;
auto x = c.foo();
writeln(x.classinfo.name); // Base
---
Comment #3 by dfj1esp02 — 2010-12-09T11:31:30Z
> x.x = 2;
> writeln (x.x); // prints 2
This just writes to the memory after the allocated Base object, probably corrupting heap.