www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 1192] New: broken overridden-function parameter list matching

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1192

           Summary: broken overridden-function parameter list matching
           Product: D
           Version: 1.013
          Platform: PC
        OS/Version: Windows
            Status: NEW
          Keywords: rejects-valid
          Severity: normal
          Priority: P3
         Component: DMD
        AssignedTo: bugzilla digitalmars.com
        ReportedBy: thecybershadow gmail.com


MyProgram.d(558): function std.string.toString called with argument types:
        (long,int)
matches both:
        std.string.toString(long,uint)
and:
        std.string.toString(ulong,uint)

The first argument has a perfect match, yet DMD is complaining about an
ambiguous match when in both matches the SECOND argument is the same!

Also, toString(x, uint) should be changed to toString(x, int) because the base
is most likely to be a literal, and numeric literals are of type int.


-- 
Apr 26 2007
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1192






I don't think that this is a bug as such.

Your code has the signature (long, int).
The library has two signatures (long, uint) and (ulong, uint) and because of
D's integer promotion rules, your code matches both the library signatures.
Thus D says its ambiguous and it needs your help to choose which one to call.

The usual cause of this is when using literals without type qualifiers. If that
is not the case then use casts. Use could also use const identifiers to improve
readibility ...

  const uint base_HEX = 16;
  char[] XX = toString( somenumber, base_HEX);



-- 
Apr 26 2007
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1192






I think it's a bug, because for (long,int) it suggests:
1: (long,uint) - one out of two parameters don't match the type exactly
2: (ulong,uint) - both parameters don't have an exactly matching type

Why suggest something that is obviously an even worse match?


-- 
Apr 26 2007
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1192






The compiler is not *suggesting* anything. It is *telling* you that the library
has two functions that BOTH could be used by your call signature, given D's
integer promotion rules, and that it doesn't know which one of those two you'd
like to actually call. The compiler is really asking for your help and not
suggesting anything at all.


-- 
Apr 26 2007
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1192






"suggest" was a bad word. Perhaps "getting confused over"? I think you
understood what I had in mind. Why would it be confused when the choice is
obvious? It can automatically convert from int to uint. Are you saying that
when the choice comes to choosing whether to convert a long to either a long or
to an ulong, both have the same priority and a conflict ensues? I don't think
so. This program:

void processLong(long x){}
void processLong(ulong x){}

void main() { long x; processLong(x); }

compiles perfectly. So obviously, the compiler doesn't take into consideration
every argument by itself, but compares the argument lists as a whole, unable to
see when one match is obviously better than the other.

I hope I made myself clear this time.


-- 
Apr 26 2007
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1192






As I said earlier, the problem is when one uses literals. The compiler is quite
inflexible when it comes to assigning type to literals.

Try this ...

  void processLong(long x){}
  void processLong(ulong x){}

  void main() { processLong(42); }

Now it complains because '42' could be either a long or ulong and it doesn't
know which one you meant. So code one of these below instead ...

  void main() { processLong(42U); }
OR
  void main() { processLong(42L); }

now it stops complaining.

Seriously, if you saw '42' in someone's code how would you decide which of the
functions to call?


-- 
Apr 26 2007
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1192






Yes, I understand that - but the parameter that varies isn't the one with the
literal at all! My code does something like .toString(x, 16) - I understand
that 16 can't be silently converted to uint, but what's the deal with the first
parameter, which is explicitely a long. Because the second parameter doesn't
exactly match, the compiler gets confused by the presence of two functions with
different types for the first parameter, for which there is an exact match
anyway... argh!


-- 
Apr 26 2007
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1192






Vladimir,
 you want compiler to become little smarter. While this is very resonable it
probably has associated costs (like compilation time). This expliciti
enforcment is not so bad and could even pay you one day, when some library API
will change or things like that.

IMHO for now - it's wanted behaviour, not a bug. But maybe it will change one
day.


-- 
Apr 27 2007
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1192


csantander619 gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |INVALID





As Derek and Dawid have said, this is intended behavior. See "Function
Overloading" in http://www.digitalmars.com/d/function.html


-- 
Apr 27 2007