DIP 1015--Deprecation of Implicit Conversion of Int. & Char. Literals to bool--Formal Assement

Rubn where at is.this
Tue Nov 13 23:29:26 UTC 2018


On Monday, 12 November 2018 at 22:07:39 UTC, Walter Bright wrote:
> On 11/12/2018 12:34 PM, Neia Neutuladh wrote:
>> Tell me more about this "consistency".
>
> int f(short s) { return 1; }
> int f(int i) { return 2; }
>
> enum : int { a = 0 }
> enum A : int { a = 0 }
>
> pragma (msg, f(a));   // calls f(int)
> pragma (msg, f(A.a)); // calls f(short)
>
> I.e. it's consistent.
>
> Here's how it works:
>
> f(a): `a` is a manifest constant of type `int`, and `int` is an 
> exact match for f(int), and f(short) requires an implicit 
> conversion. The exact match of f(int) is better.
>
> f(A.a): `a` is an enum of type `A`. `A` gets implicitly 
> converted to `int`. The `int` then gets exact match to f(int), 
> and an implicit match to f(short). The sequence of conversions 
> is folded into one according to:
>
>     <implicit conversion> <exact>               => <implicit 
> conversion>
>     <implicit conversion> <implicit conversion> => <implicit 
> conversion>
>
> Both f(int) and f(short) match, because implicit conversions 
> rank the same. To disambiguate, f(short) is pitted against 
> f(int) using partial ordering rules,
> which are:
>
>     Can a short be used to call f(int)? Yes.
>     Can an int be used to call f(short)? No.
>
> So f(short) is selected, because the "Most Specialized" 
> function is selected when there is an ambiguous match.
>
> Note: the "most specialized" partial ordering rules are 
> independent of the arguments being passed.
>
> ---
>
> One could have <implicit conversion><exact> be treated as 
> "better than" <implicit conversion><implicit conversion>, and 
> it sounds like a good idea, but even C++, not known for 
> simplicity, tried that and had to abandon it as nobody could 
> figure it out once the code examples got beyond trivial 
> examples.

This just seems like a bug to me. Any sane human being would 
expect all these functions to output the same thing. But it 
entirely depends on how you use it.

import std.stdio;

void foo(byte v) { writeln("byte ", v); }
void foo(int v) { writeln("int ", v); }

enum : int { a = 127 }
enum A : int { a = 127 }

void main()
{
     A v = A.a;
     foo(A.a); // byte 127 < These two are probably the best 
showcase of what's wrong
     foo(v);   // int 127  < same values being passed with same 
type but different result

     foo(a);   // int 127
     foo(127); // int 127
}

https://run.dlang.io/is/aARCDo



More information about the Digitalmars-d-announce mailing list