Deprecate implicit conversion between signed and unsigned integers

Quirin Schroll qs.il.paperinik at gmail.com
Thu Feb 6 15:18:18 UTC 2025


On Wednesday, 5 February 2025 at 16:29:25 UTC, Paul Backus wrote:
> On Tuesday, 4 February 2025 at 16:29:22 UTC, Quirin Schroll 
> wrote:
>> Any implicit conversions? I’d boldly claim the following 
>> conversions are unproblematic:
>> * `float` → `double` → `real`
>> * signed integer → bigger signed integer
>> * unsigned integer → bigger unsigned integer
>>
>> And it would be really annoying to have to explicitly cast 
>> them.
>
> In general, implicit conversions that preserve the value range 
> of the original type are ok. So, for example:
>
> * `ushort` → `int`
> * `long` → `float`
>
> The reason that conversions like `int` → `uint` and `uint` → 
> `int` are problematic is that the value range of the original 
> type does not fit into the value range of the target type.

I even think that implicit conversions from integral to 
floating-point type are bad, considering that `int` → `float` and 
`long` → `double` aren’t lossless in general.

Here’s an attempt to classify:
1. Definitely okay implicit conversions:
     * `float` → `double` → `real`
     * `byte` → `short` → `int` → `long`
     * `ubyte` → `ushort` → `uint` → `ulong`
2. Probably okay implicit conversions:
     * `ubyte` → `short` → `int` → `long`
     * `ushort` → `int` → `long`
     * `uint` → `long`
3. Somewhat contentious implicit conversions:
     * `byte`/`ubyte`/`short`/`ushort` → `float` → `double` → 
`real`
     * `int`/`uint` → `double` → `real`
     * `long`/`ulong` → `real`
4. Micro-lossy narrowing conversions:
     * `int`/`uint` → `float`
     * `long`/`ulong` → `float`/`double`
5. Bit-pattern-preserving value-altering conversions:
     * `byte` ↔ `ubyte`
     * `short` ↔ `ushort`
     * `int` ↔ `uint`
     * `long` ↔ `ulong`
6. Lossy narrowing conversions:
     * The reverse of any “→” above.

It appears to me that you can reasonably draw 7 lines (from 
before 1 to after 6). Examples for what existing languages do (to 
my knowledge):
* Haskell draws the line at 0/1. It has no implicit conversions 
whatsoever.
* C# draws the line at 4/5.
* D draws the line at 5/6.
* C/C++ draws the line at 6/7.


More information about the dip.ideas mailing list