C++ Logo

std-discussion

Advanced search

Re: Implicit conversion sequence from literal 0

From: Edward Catmur <ecatmur_at_[hidden]>
Date: Sun, 8 Jan 2023 11:24:44 +0000
On Sun, 8 Jan 2023, 11:18 Lénárd Szolnoki via Std-Discussion, <
std-discussion_at_[hidden]> wrote:

> On Sun, 8 Jan 2023 03:02:14 +0100
> Phil via Std-Discussion <std-discussion_at_[hidden]> wrote:
>
> > The example code favors the first overload because the 2nd argument
> > (integer literal -> int -> Identity -> Exact Match) does not need to
> > get narrowed to short like needed for the second overload (Integral
> > conversions -> Conversion), i.e. it has a better rank.
> >
> > If you explicitly cast the 2nd argument to short, the second overload
> > gets selected because of identity match for 2nd parameter. There is
> > of course no ambiguity because the first overload (with an int as
> > second parameter) would require a integral promotion which has rank
> > promotion, but the identity match with short is still better (exakt
> > match).
> >
> > If you change the 2nd parameter for the second overload from short to
> > int/long, you will get ambiguity, because the first argument is
> > always ambiguous since converting 0 to short as well as converting 0
> > to void* are conversions and have the same rank. It just depends on
> > the second parameter.
> >
> > If all shorts would be changed to ints, the second overload would be
> > selected, since it had two times identity -> exact match (for both
> > parameters). If the first overload changed its second parameter from
> > int to short, there would be ambiguity again, since the compiler can
> > not tell which conversion is "better": converting the first argument
> > to void* or the second to short (both have rank: Conversion).
>
> The example is deliberately crafted this way, so when both functions
> are viable, the one with the `void *` is chosen, as it's more viable. If
> only `void foo(short, short)` were viable, then it would be chosen
> instead.
>
> I agree that *if* `void foo(void*, int)` is viable, then it is also the
> most viable. The question is if `void foo(void*, int)` viable or not.
>
> > Therefore I do not see that this is an issue or related to
> > "null-pointers". Or do I miss the point for this discussion
> > completely?
>
> I think you do. The point is that according to the wording, the call
> `foo(0, 1)` wouldn't find the function `void foo(void *, int)` viable
> at all, even though `0` can be converted to `void *` in general, as
> (quoting the standard) "implicit conversion sequences are concerned
> only with the type, cv-qualification, and value category of the
> argument...". In this case `void foo(short, short)` is the only viable
> overload, so that function should be called.
>
> Basically according to the current wording, the viable overloads are
> resolved for `foo(0, 1)` the same way as for `foo(1, 1)`.
>

... because literal 0 and literal 1 have the same type, cv and value
category.

So `foo(0, 1)` would be expected to behave the same as `foo(1, 1)`.

Sorry if this is laboring the point.

>

Received on 2023-01-08 11:24:58