www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - subclass overload bug

reply Ant <duitoolkit yahoo.ca> writes:
again the method lookup resolution is not satisfactory.

compiling the example we get:
Over.d(32): function func overloads void(int i) and void(float f) both match
argument list for func

if we uncomment all the functions every thing goes as expected:
B.func char a

and who told who to automatically conver char to float?

(commenting out b.func(int) will produce the output:
B.func float 97.000000)

(I don't care how C++ does it)

Ant
---------------------------------------------

class A
{
	public:
	void func(char a)
	{
		printf("A.func char \n" );
	}
}

class B : A
{
	public:
	void func(int i)
	{
		printf("B.func int %d\n" ,i);
	}
//	void func(char a)
//	{
//		printf("B.func char %c\n" ,a);
//	}
	void func(float f)
	{
		printf("B.func float %f\n" ,f);
	}
}

void main()
{
	
	B b = new B();
	b.func('a');
	
}
Sep 22 2004
next sibling parent reply Stewart Gordon <Stewart_member pathlink.com> writes:
In article <pan.2004.09.22.16.02.36.893063 yahoo.ca>, Ant says...

 again the method lookup resolution is not satisfactory.
 
 compiling the example we get: Over.d(32): function func overloads 
 void(int i) and void(float f) both match argument list for func

 and who told who to automatically conver char to float?

Walter, at a guess. It's really a combination of two rules: (a) "In D, function overloading is simple. It matches exactly, it matches with implicit conversions, or it does not match. If there is more than one match, it is an error." Though I think that was actually meant to say: "If it doesn't match exactly and there is more than one match with implicit conversions, it is an error." (b) a rule carried over from C++, whereby if a derived class method happens to have the same name as one in the base class, but the parameter types don't match, the derived hides the base. Presumably, it's supposed to protect the programmer creating a subclass of a third-party class from improvements. Good question though ... is char implicitly converting to float the Right Thing? Stewart.
Sep 22 2004
parent reply Sean Kelly <sean f4.ca> writes:
In article <ciscbi$2on5$1 digitaldaemon.com>, Stewart Gordon says...
Good question though ...  is char implicitly converting to float the 
Right Thing?

I would be inclined to say no, except that it does follow standard promotion rules. If an int can be implicitly coverted to float, why not char? Sean
Sep 22 2004
parent reply Nick <Nick_member pathlink.com> writes:
In article <cishs2$2s3k$1 digitaldaemon.com>, Sean Kelly says...
In article <ciscbi$2on5$1 digitaldaemon.com>, Stewart Gordon says...
Good question though ...  is char implicitly converting to float the 
Right Thing?

I would be inclined to say no, except that it does follow standard promotion rules. If an int can be implicitly coverted to float, why not char?

If a char is implicitly an int, and an int is implicitly a float, then a char should implicitly be a float. Nick
Sep 22 2004
parent Stewart Gordon <Stewart_member pathlink.com> writes:
In article <cisn1h$2v2e$1 digitaldaemon.com>, Nick says...
<snip>
 If a char is implicitly an int, and an int is implicitly a float, 
 then a char should implicitly be a float.

AIUI implicit conversions aren't generally transitive. For example, char[] implicitly converts to char*, which implicitly converts to void*, but char[] doesn't implicitly convert to void*. If arbitrarily long chains of implicit conversions happened, it might get a bit confusing and complicated. Stewart.
Sep 24 2004
prev sibling parent reply Sean Kelly <sean f4.ca> writes:
In article <pan.2004.09.22.16.02.36.893063 yahoo.ca>, Ant says...
again the method lookup resolution is not satisfactory.

compiling the example we get:
Over.d(32): function func overloads void(int i) and void(float f) both match
argument list for func

if we uncomment all the functions every thing goes as expected:
B.func char a

and who told who to automatically conver char to float?

(commenting out b.func(int) will produce the output:
B.func float 97.000000)

(I don't care how C++ does it)

Then I suppose you don't care that C++ would pick the 'int' function rather than complaining about ambiguous overloads? D tries to simplify overload resolution (which is possibly the most complicated feature of C++) by defining a very simple set of rules: "In D, function overloading is simple. It matches exactly, it matches with implicit conversions, or it does not match. If there is more than one match, it is an error." While the C++ method may be more convenient is some instances, the D method is less prone to unexpected errors (and far simpler to implement from a compiler perspective). And really, all that's required to fix things is a cast: void func( int x ) {} void func( float x ) {} func( cast(int) 'a' ) {} Sean
Sep 22 2004
parent reply Ant <duitoolkit yahoo.ca> writes:
On Wed, 22 Sep 2004 18:54:15 +0000, Sean Kelly wrote:

 In article <pan.2004.09.22.16.02.36.893063 yahoo.ca>, Ant says...
(I don't care how C++ does it)

Then I suppose you don't care that C++ would pick the 'int' function rather than complaining about ambiguous overloads? D tries to simplify overload resolution (which is possibly the most complicated feature of C++) by defining a very simple set of rules: "It matches exactly, it matches with implicit conversions, or it does not match. If there is more than one match, it is an error."

obviously we need to change to "In D, function overloading is simple: Matches exacly, or it does not match. If there is more than one match, it is an error." that's the only way to go.
 
 While the C++ method may be more convenient is some instances, the D method is
 less prone to unexpected errors (and far simpler to implement from a compiler
 perspective).  And really, all that's required to fix things is a cast:
 
 void func( int x ) {}
 void func( float x ) {}
 
 func( cast(int) 'a' ) {}

or better yet drop the implicit conversion and do: func( 'a' ) --- > error func( cast(int) 'a' ); // ok func( cast(float) 'a' ); //ok Ant
Sep 22 2004
parent Stewart Gordon <Stewart_member pathlink.com> writes:
In article <pan.2004.09.22.20.17.34.492063 yahoo.ca>, Ant says...

 On Wed, 22 Sep 2004 18:54:15 +0000, Sean Kelly wrote:
 
 In article <pan.2004.09.22.16.02.36.893063 yahoo.ca>, Ant says...
 
 (I don't care how C++ does it)

Then I suppose you don't care that C++ would pick the 'int' function rather than complaining about ambiguous overloads? D tries to simplify overload resolution (which is possibly the most complicated feature of C++) by defining a very simple set of rules: "It matches exactly, it matches with implicit conversions, or it does not match. If there is more than one match, it is an error."

obviously we need to change to "In D, function overloading is simple: Matches exacly, or it does not match. If there is more than one match, it is an error."

If it's at all possible to have multiple exact matches, the only ways I can see are by defargs or varargs. In which case, I'd guess the one that matches without taking either into account would win.
 that's the only way to go.

But it would uglify programs with casts all over the place. <snip>
 or better yet drop the implicit conversion and do:
 
 func( 'a' ) --- > error
 func( cast(int) 'a' ); // ok
 func( cast(float) 'a' ); //ok

Already the way it works in this instance. Stewart.
Sep 23 2004