1
void foo(int,int) {}
void foo(int ,float) {}
void foo(float,int) {}

void main()
{
  unsigned int i = 10;
  unsigned float f = 1.0;       //line 5
  foo(i,f); // ambiguous call error
}

replacing line 5 by

float f = 1.0;

makes the program work. Why is it so?

I am working on visual studio 2005.

Praetorian
  • 106,671
  • 19
  • 240
  • 328
Suri
  • 3,287
  • 9
  • 45
  • 75
  • 8
    What kind of data type is `unsigned float`? – Praetorian Jul 17 '11 at 06:41
  • compiler is neither showing error nor warning.this is making me confused also.any clue? – Suri Jul 17 '11 at 06:46
  • Well, it is a 6 year old compiler. You should use a newer version unless someone is forcing you to use VS2005. Visual Studio has a free version call Express Edition, google it and download the 2010 version. Or there is always MinGW (it's free too). – Praetorian Jul 17 '11 at 06:53

4 Answers4

5

There is no such data type as unsigned float. Pay attention to compiler warnings; if you're not getting any bump up the warning level. From running this example on Visual Studio 2010 it looks like the compiler ignores the float keyword in the declaration

unsigned float f = 1.0;

This makes f an unsigned int. Since you don't have an overload of foo() that takes an int and unsigned int the compiler is unable to deduce which overload to call. If you add another overload

void foo(int,unsigned int) {}

the ambiguous call error disappears.

Praetorian
  • 106,671
  • 19
  • 240
  • 328
  • then it should call foo(int,int) as unsigned int is promoted to int instead of showing ambiguity – Suri Jul 17 '11 at 06:52
  • @Suri: unsigned int to int is not a promotion since the latter has a smaller range than the former – Praetorian Jul 17 '11 at 06:57
  • yes u r right.so does it means that conversion from unsigned int to int or float have same priority when overloding function are resolved?It is not like that unsigned int to int have higher priority – Suri Jul 17 '11 at 07:01
3

Conversion from unsigned int to either int or float results in a loss of precision, and both are considered equal by the compiler. You have to add an explicit case to make the compiler decide which to use, e.g.:

foo(i, static_cast<float>(f));

Note that there is no such thing as unsigned float. If the compiler accepts that, it is not standards-compliant (VC2010 warns about it, not sure about VC2005).


The relevant sections of the C++98 standard are section 4, which ranks a numeric type cast as either an exact match, a promotion, or a conversion, and section 13.3.3.2, which defines how implicit conversions are ranked for overload resolution. The latter section states, in subparagraph 4:

Standard conversion sequences are ordered by their ranks: an Exact Match is a better conversion than a Promotion, which is a better conversion than a Conversion.

Conversion from unsigned int to either float or int is ranked as "Conversion" either way, so it is "indistinguishable", making the overload ambiguous.

Since unsigned float is not an actual type according to the standard, it's hard to say how this applies in your situation, but your compiler appears to treat conversion from unsigned float to either float or int as indistinguishable too.

Sven
  • 21,903
  • 4
  • 56
  • 63
0

When you make f float there is only one function that can be called - so no ambiguity. It works, because unsigned int can be cast to int silently.

Petar Ivanov
  • 91,536
  • 11
  • 82
  • 95
0

What kind of type is unsigned float?? Nothing that I've ever heard of. Check this.

As far as I understand, floating point types (i.e. float, double etc) are always signed.

EDIT: This will not compile at ideone (which is gcc 4.3.4) (it throws the error "invalid signed/unsigned with float"):

int main()
{
    unsigned float ff = 1.0;

    return ff;
}

I dunno what MSVC is doing if it accepts unsigned float. I don't think it's a valid type.

Community
  • 1
  • 1
Darren Engwirda
  • 6,915
  • 4
  • 26
  • 42
  • compiler is neither showing error nor warning.this is making me confused also.any clue? – Suri Jul 17 '11 at 06:45