PROPOSAL: Implicit conversions of integer literals to floating point

Robert Jacques sandford at jhu.edu
Wed Dec 29 23:00:20 PST 2010


On Wed, 29 Dec 2010 23:46:19 -0700, Don <nospam at nospam.com> wrote:

> BACKGROUND:
> D currently uses a very simple rule for parameter matching:
> * it matches exactly; OR
> * it matches using implicit conversions; OR
> * it does not match.
>
> There's an important extra feature: polysemous literals (those which can  
> be interpreted in multiple ways) have a preferred interpretation.
> So 'a' is char (rather than wchar or dchar); 57 is an int (rather than  
> short, byte, long, or uint); and 5.0 is a double (rather than float or  
> real).
> This feature acts as a tie-breaker in the case of ambiguity. Notice that  
> the tie-breaking occurs between closely related types.
> If you implement overloading on any two of the possibilities, you would  
> always overload the preferred type anyway. (eg, it doesn't make sense to  
> overload 'short' and 'uint' but not 'int'). So this all works in a  
> satisfactory way.
>
> THE PROBLEM:
> Unfortunately, the tie-breaking fails for integer literals used as  
> floating-point parameters.
> Consider:
>
> void foo(double x) {}
>
> void main()
> {
>     foo(0);
> }
>
> This compiles correctly; 0 converts to double using implicit  
> conversions. Now add:
> void foo(real x) {}
> void foo(float x) {}
> And now the existing code won't compile, because 0 is ambiguous.
> Adding such overloads is a common activity. It is totally unreasonable  
> for it to break existing code, since ANY of the overloads would be  
> acceptable.
>
> The language doesn't have any reasonable methods for dealing with this.  
> The only one that works at all is to add a  foo(int) overload. But it  
> scales very poorly -- if you have 4 floating point parameters, you need  
> to add 15 overloads, each with a different combination of int  
> parameters. And it's wrong -- it forces you to allow int variables
> to be accepted by the function (but not uint, short, long !) when all  
> you really need is for literals to be supported.
>
> And no, templates are most definitely not a solution, for many reasons  
> (they break even more code, they can't be virtual functions, etc)
>
> This problem has already hit Phobos. We inserted a hack so that sqrt(2)  
> will work. But exp(1) doesn't work.
> Note that the problems really arise because we've inherited C's rather  
> cavalier approach to implicit conversion.
>
> PROPOSAL:
>
> I don't think there's any way around it: we need another level of  
> implicit conversion, even if only for the special case of integer  
> literals->floating point.
>  From the compiler implementation point of view, the simplest way to do  
> this would be to add a level between "exact" and "implicit". You might  
> call it "matches with preferred conversions", or "match with literal  
> conversions".
>
> A match which involves ONLY conversions from integer literals to double,  
> should be regarded as a better match than any match which includes any  
> other kind of implicit conversion.
> As usual, if there is more than one "preferred conversion" match, it is  
> flagged as ambiguous.
>
> BTW, I do not think this applies to other literals, or other types. It  
> only applies to polsemous types, and int literal->floating point is the  
> only such case where there's no tie-breaker in the target type.
>
> It's a very special case, but a very common and important one. It  
> applies to *any* overloaded floating point function. So I think that a  
> special case in the language is justified.

vote++.


More information about the Digitalmars-d mailing list