import std.stdio;
class Base
{
string f()
{
return "Base.f()";
}
}
class Derived : Base
{
string f()
{
return "Derived.f()";
}
string f() const // or immutable
{
return "Derived.f() const";
}
}
void main()
{
auto x = new Base;
writeln(x.f());
auto y = new Derived;
writeln(y.f());
auto z = new const(Derived); // or immutable
writeln(z.f()); //object.Error: Access Violation
}
Comment #1 by rayerd.wiz — 2009-10-19T03:22:09Z
This problem occurs when "const" is "shared".
Comment #2 by r.sagitario — 2010-01-22T00:37:37Z
This kind of works now with changeset 344. But both "f()" and "f() const" overload "f()" in the base class, and the last one wins. I think dmd should either issue an error or add another entry to the vtbl for the non-exact but covariant match.
Comment #3 by rayerd.wiz — 2010-01-30T23:34:40Z
This problem's characteristics changed at dmd2.040.
import std.stdio;
class Base
{
string f()
{
return "Base.f()";
}
}
class Derived : Base
{
string f()
{
return "Derived.f()";
}
string f() immutable
{
return "Derived.f() immutable";
}
string f() shared
{
return "Derived.f() shared";
}
}
void main()
{
auto x = new Base;
writeln(x.f());
auto y = new Derived;
writeln(y.f());
auto z = new immutable(Derived);
//main.d(15): Error: function main.Derived.f of type immutable string() overrides but is not covariant with main.Base.f of type string()
writeln(z.f());
auto w = new shared(Derived);
//main.d(19): Error: function main.Derived.f of type shared string() overrides but is not covariant with main.Base.f of type string()
writeln(w.f());
}
Are both errors correctly?
I expected that z.f() calls "Derived.f() immutable" and w.f() calls "Derived.f() shared".
Comment #4 by bugzilla — 2012-01-23T01:28:50Z
I believe the errors are correct.
Comment #5 by timon.gehr — 2012-01-23T13:41:57Z
I think it is a bug. The derived class introduces two additional overloads. The compiler claims that all three overloads override the same function.
Comment #6 by bugzilla — 2012-01-23T15:47:44Z
(In reply to comment #5)
> I think it is a bug. The derived class introduces two additional overloads. The
> compiler claims that all three overloads override the same function.
The error messages are deliberate.
Comment #7 by timon.gehr — 2012-01-23T16:37:46Z
If so, why is this code accepted?
class A{
void f(int){}
}
class B: A{
override void f(int){}
void f(immutable int){}
void f(shared int){}
}
What is the point of deliberately treating the hidden this pointer special regarding overloading?
Comment #8 by timon.gehr — 2012-01-23T16:39:10Z
Furthermore, this works, of course:
class B{
void f(int){}
void f(int)immutable{}
void f(int)shared{}
}
Comment #9 by bugzilla — 2012-01-23T19:36:45Z
The return types are the issue. You cannot, for example, override a function that returns a mutable array with one that returns an immutable one. It would be a giant hole in the type system.
Comment #10 by timon.gehr — 2012-01-24T07:18:45Z
The signature of the overriding function is identical to the overridden one in all cases discussed here.
class A{
void f(){} // note: return type void
}
class B: A{
override void f(){} // overrides base f
void f()immutable{} // new overload
void f()shared{} // new overload
}
It is impossible to break the type system (even if the return types would be different): the new overloads are not even reachable through a base class reference. The bug is that the compiler does not take into account the storage class of the hidden this pointer while deciding what overrides what.