Topic: is long+int ambiguous


Author: jbarfurth@vossnet.de (Joerg Barfurth)
Date: 1999/11/22
Raw View
Gene Bushuyev <gbush@my-deja.com> wrote:

> I guess standard should have chosen long type for integral promotions i=
n 4.5
> instead of int. Am I missing something?

Yes: clause 5/p.9

-- J=F6rg Barfurth
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: jbarfurth@vossnet.de (Joerg Barfurth)
Date: 1999/11/22
Raw View
William E. Aitken <aitken@halcyon.com> wrote:

>   Conversion from int to long is not a promotion.   See 4.5.   The real
That is true.

> answer is that 13.6 P 12, adds all prototypes of the following form > >=
 LR
operator +(L, R) Sorry, that is wrong: 13.3.1.2/1 states that, if both
operands are builtin types, use of the built-in operator is assumed
without doing overload resolution.

13.6/1 states that the listed candidate operator functions are only used
for overload resolution according to 13.3.1.2 and for NO OTHER PURPOSE.

It further refers to section 5 for what conversions are actually done if
a builtin operator is selected by overload resolution.
> where L and R are promoted arithmetic types and LR is the result of the
> usual arithmetic conversions on L and R.   In particular, this means th=
at
Now this gives us a clue: Have look at the usual arithmetic conversions.
> there are these prototypes
>=20
> long operator(int, long) long, int)
>=20
> since both int and long are promoted arithmetic types.

As pointed out that isn't relevant here. But looking for "usual
arithmetic conversions" we find 5/9 which answers the original posters
question.
I read 13.3.1.2 as saying that there is only one built-in binary
operator +. No overload resolution is done, therefore no ambiguity is
possible.
The one built-in operator accepts different combinations of arguments
with special rules how to traet them. That is why they are built-in and
cannot be part of the standard library: They behave differently than
ordinary (operator) functions.

<SIDEBAR>
13.6 applies in cases like:

struct X {}
int operator+(X , long);

struct A { operator long(); operator X(); };
struct B { operator short(); };

int c =3D A() + B(); // [*]

In overload resolution for [*] we have to consider
    operator +(X, long);    // user-defined
and
    operator +(long, int);  // candidate from 13.6

As the left operand in each case requires a single user-defined
conversion (so they are equally good), we look at the right operand:
    B =3D> short =3D > long is worse than
    B =3D> short =3D> int
as the latter needs only an integral promotion, while the former
requires an integral conversion after the user-defined conversion.

So this selects built-in operator+. But now, by the rules from 5/9 the
operand of the right hand side is actually converted to a long, instead
of just promoting to an int.=20
Nevertheless the expression [*] should not be ambiguous as I read the
standard.=20
I'll check my compiler on that one soon...
</SIDEBAR>

-- J=F6rg Barfurth
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Gene Bushuyev" <gbush@my-deja.com>
Date: 1999/11/19
Raw View
According to 4.7 chapter of current standard both int->long and long->int
are integral conversions. Therefore, long+int has two candidate operators:
"int operator+(int,int)" and "long operator+(long,long)". Both are viable
functions, neither is better than the other: the call is ambiguous.
Neveretheless, as one may expect, all compilers do compile this code and
none of them complains.
I guess standard should have chosen long type for integral promotions in 4.5
instead of int. Am I missing something?
--
----------------
Gene Bushuyev
Entia non sunt multiplicanda praeter necessitatem
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: jcoffin@taeus.com (Jerry Coffin)
Date: 1999/11/20
Raw View
In article <s38uclr51eo54@corp.supernews.com>, gbush@my-deja.com
says...
> According to 4.7 chapter of current standard both int->long and long->int
> are integral conversions. Therefore, long+int has two candidate operators:
> "int operator+(int,int)" and "long operator+(long,long)". Both are viable
> functions, neither is better than the other: the call is ambiguous.

Not so.

> Neveretheless, as one may expect, all compilers do compile this code and
> none of them complains.

Of course.

> I guess standard should have chosen long type for integral promotions in 4.5
> instead of int. Am I missing something?

Yup.  See 13.3.3.1.1, table 9.  It lists conversions in descending
order of preference when they must be used to match overloaded
functions.  Conversion from int to long is a promotion, so it falls
into the "promotion" category for matching.  Conversion from long to
int is NOT a promotion, so it falls into the "conversion" category for
matching.  A promotion is preferable to a conversion, so the long is
the one that should be matched.

The only time the call is ambiguous is if there are two conversions
that fall into the same category.  For example, if you had two
functions that took the same type, but with different qualifications
(e.g. one took a const and the other a non-const qualified version of
the same type) they'd both fall into the "exact match" category, and
the call would be ambiguous.  For another example, if you had:

void f(bool);
void f(int);

and tried to call:

f(10L);

You'd have an ambiguous call because the conversion from long to int
and the conversion from long to bool both fall into the conversion
category.  You could cure this by adding (for example) a third
overload that accepted a long as the parameter, so it would be
preferred to either of the overloads above.

--
    Later,
    Jerry.

The universe is a figment of its own imagination.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: aitken@halcyon.com (William E. Aitken)
Date: 1999/11/20
Raw View
In article <MPG.129f9bf53d33de34989851@news.mindspring.com>,
Jerry Coffin <jcoffin@taeus.com> wrote:
>
>In article <s38uclr51eo54@corp.supernews.com>, gbush@my-deja.com
>says...
>> According to 4.7 chapter of current standard both int->long and long->int
>> are integral conversions. Therefore, long+int has two candidate operators:
>> "int operator+(int,int)" and "long operator+(long,long)". Both are viable
>> functions, neither is better than the other: the call is ambiguous.
>
>Not so.
>
>> Neveretheless, as one may expect, all compilers do compile this code and
>> none of them complains.
>
>Of course.
>
>> I guess standard should have chosen long type for integral promotions in 4.5
>> instead of int. Am I missing something?
>
>Yup.  See 13.3.3.1.1, table 9.  It lists conversions in descending
>order of preference when they must be used to match overloaded
>functions.  Conversion from int to long is a promotion, so it falls
>into the "promotion" category for matching.  Conversion from long to
>int is NOT a promotion, so it falls into the "conversion" category for
>matching.  A promotion is preferable to a conversion, so the long is
>the one that should be matched.
>

 Conversion from int to long is not a promotion.   See 4.5.   The real
answer is that 13.6 P 12, adds all prototypes of the following form

LR operator +(L, R)

where L and R are promoted arithmetic types and LR is the result of the usual
arithmetic conversions on L and R.   In particular, this means that there
are these prototypes

long operator(int, long)
long operator(long, int)

since both int and long are promoted arithmetic types.



--
William E. Aitken        | Formal verification is the
email: aitken@halcyon.com                   |  future of computer science ---
Snail: 6124 86th Ave SE Mercer Island WA    | Always has been, always will be.
===============================================================================


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]