www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - bug: method override via overload

reply pragma <pragma_member pathlink.com> writes:
Apologies if this has been posted before:

The compiler seems to accept the method overload for 'bar' with a different type
of argument, yet it fails to resolve the correct overload when that method is
called.  Near as I can tell, since both int and Foo are technically the same
type, the base class method is being completly overriden - is this a type
covariance issue?

One can change the return type of the overriden method to match the overriding
one, suggesting that the compiler wants to treat both methods as distinct (it
doesn't complain that they match).  Perhaps Typedef is to blame here?

# typedef int Foo;
# 
# class Gorf{
# 	public void bar(int x){} // return type here is immaterial (try 'int')
# }
# 
# class Goat : Gorf{
# 	public int bar(Foo x){}
# }
# 
# void main(){
# 	Foo y = 0;
# 	int z = 0;
# 	Goat g = new Goat();
# 	g.bar(y); // works
# 	g.bar(z); // fails
# }


- Eric Anderton at yahoo
Feb 20 2006
next sibling parent reply Nick <Nick_member pathlink.com> writes:
In article <dtcoqg$22lv$1 digitaldaemon.com>, pragma says...
# typedef int Foo;
# 
# class Gorf{
# 	public void bar(int x){} // return type here is immaterial (try 'int')
# }
# 
# class Goat : Gorf{
# 	public int bar(Foo x){}
# }
# 
# void main(){
# 	Foo y = 0;
# 	int z = 0;
# 	Goat g = new Goat();
# 	g.bar(y); // works
# 	g.bar(z); // fails
# }

This is by design, not a bug. When you introduce members with the same name in a child class, you automatically hide the inherited name from the parent. There are good reasons to do this, and C++ does it the same way. Add the line alias Gorf.bar bar; to Goat to get it the way you want. (BTW this question comes up a lot - perhaps it's time to make a FAQ for these groups?) Nick
Feb 20 2006
parent reply Ant <Ant_member pathlink.com> writes:
In article <dtcpkd$23ii$1 digitaldaemon.com>, Nick says...
In article <dtcoqg$22lv$1 digitaldaemon.com>, pragma says...
# typedef int Foo;
# 
# class Gorf{
# 	public void bar(int x){} // return type here is immaterial (try 'int')
# }
# 
# class Goat : Gorf{
# 	public int bar(Foo x){}
# }
# 
# void main(){
# 	Foo y = 0;
# 	int z = 0;
# 	Goat g = new Goat();
# 	g.bar(y); // works
# 	g.bar(z); // fails
# }

This is by design, not a bug. When you introduce members with the same name in a child class, you automatically hide the inherited name from the parent. There are good reasons to do this

Where are those? I try to look for them but only found the ones from Bjarne and Bright... Ant
Feb 21 2006
parent reply pragma <pragma_member pathlink.com> writes:
In article <dtf9t2$1vjk$1 digitaldaemon.com>, Ant says...
In article <dtcpkd$23ii$1 digitaldaemon.com>, Nick says...
In article <dtcoqg$22lv$1 digitaldaemon.com>, pragma says...
# typedef int Foo;
# 
# class Gorf{
# 	public void bar(int x){} // return type here is immaterial (try 'int')
# }
# 
# class Goat : Gorf{
# 	public int bar(Foo x){}
# }
# 
# void main(){
# 	Foo y = 0;
# 	int z = 0;
# 	Goat g = new Goat();
# 	g.bar(y); // works
# 	g.bar(z); // fails
# }

This is by design, not a bug. When you introduce members with the same name in a child class, you automatically hide the inherited name from the parent. There are good reasons to do this

Where are those?

Exactly what I'm trying to figure out. ;) BTW, thank you Nick: your suggested workaround via 'alias' worked great. Anyway, my main problem with this behavior is that if Foo were a class, the code in main() would compile and behave just fine. So why such an inconsistency could be tolerated, is beyond me. Also the docs say (for the most part) that this shouldn't happen: "Strong types can be introduced with the typedef. Strong types are semantically a distinct type to the type checking system, for function overloading, and for the debugger." # typedef int myint; # # void foo(int x) { } # void foo(myint m) { } # # myint b; # foo(b); // calls foo(myint) So it works fine with overloads in the same scope, but fails when typedefs overlap with inherited methods that posess the same underlying type. That smells like a bug to me. - Eric Anderton at yahoo
Feb 21 2006
parent reply Nick <Nick_member pathlink.com> writes:
In article <dtg3cl$2ru6$1 digitaldaemon.com>, pragma says...
Anyway, my main problem with this behavior is that if Foo were a class, the
code in main() would compile and behave just fine.  So why such an
inconsistency could be tolerated, is beyond me.

Well actually it doesn't work, it behaves the same way. Try it :) Unlike many quirks from C++, Walter opted to keep this one. I'm not really sure either way if it is good or bad, though. Perhaps it would be good to change it since so many people find it counter-intuitive. I guess I've just gotten used to it from C++. Nick
Feb 22 2006
parent pragma <pragma_member pathlink.com> writes:
In article <dtjp93$1lra$1 digitaldaemon.com>, Nick says...
In article <dtg3cl$2ru6$1 digitaldaemon.com>, pragma says...
Anyway, my main problem with this behavior is that if Foo were a class, the
code in main() would compile and behave just fine.  So why such an
inconsistency could be tolerated, is beyond me.

Well actually it doesn't work, it behaves the same way. Try it :) Unlike many quirks from C++, Walter opted to keep this one. I'm not really sure either way if it is good or bad, though. Perhaps it would be good to change it since so many people find it counter-intuitive. I guess I've just gotten used to it from C++.

I stand corrected. Thank you for the lively discussion, and setting me straight! :)
Nick

- Eric Anderton
Feb 23 2006
prev sibling parent Nick <Nick_member pathlink.com> writes:
Oops, I missed the typedef at the begining of your example. I must have answered
on auto pilot there, sorry.

Still, I think the current behavior is correct. Even though Foo and int are
'nearly' the same type, they are not _actually_ the same type, so this is a
result of having strong typedefs in D. I guess int and Foo are treated much like
eg. float and double in this case, implicitly convertable but different types.

Nick
Feb 21 2006