Deprecate implicit conversion between signed and unsigned integers

Paul Backus snarwin at gmail.com
Sun May 12 13:32:36 UTC 2024


D inherited these implicit conversions from C and C++, where they 
are widely regarded as a source of bugs.

* In his 2018 paper, ["Subscripts and sizes should be 
signed"][1], Bjarne Stroustrup gives several examples of bugs 
caused by the use of unsigned sizes and indices in C++. About 
half of them are caused by wrapping subtraction; the other half 
are caused by implicit conversion from signed to unsigned.

* The C++20 standard includes [safe integer comparison 
functions][2] specifically to avoid these implicit conversions 
when comparing integers of different signedness.

* Both [GCC][3] and [Clang][4] provide a `-Wsign-conversion` flag 
to warn about these implicit conversions.

In D, they cause the additional problem of breaking value-range 
propagation (VRP):

     enum byte a = -1;
     enum uint b = a; // Ok, but...
     enum byte c = b; // Error - original value range has been lost

D would be a simpler, easier-to-use language if these implicit 
conversions were removed. The first step to doing that is to 
deprecate them.

While this is a breaking change, migration of old code would be 
very simple: simply insert an explicit `cast` to silence the 
error and restore the original behavior. In many cases, migration 
could be performed automatically with a tool that uses the DMD 
frontend as a library.

I believe this change would be received positively by existing D 
programmers, since D's willingness to discard C and C++'s 
mistakes is one of the things that draws programmers to D in the 
first place.

[1]: 
https://open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1428r0.pdf
[2]: https://en.cppreference.com/w/cpp/utility/intcmp
[3]: 
https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wsign-conversion
[4]: 
https://clang.llvm.org/docs/DiagnosticsReference.html#wsign-conversion


More information about the dip.ideas mailing list