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