Annoyance with new integer promotion deprecations

Jonathan M Davis newsgroup.d at jmdavisprog.com
Tue Feb 6 03:12:33 UTC 2018


On Monday, February 05, 2018 18:30:03 Walter Bright via Digitalmars-d wrote:
> On 2/5/2018 3:18 PM, Timon Gehr wrote:
> > Neither byte nor dchar are C types.
>
> "byte" is a C "signed char". On Posix systems, a dchar maps to wchar_t,
> although wchar_t is a typedef not a distinct type. It's a bit complicated
> :-)
> > The overloading rules are fine, but byte should not implicitly convert
> > to
> > char/dchar, and char should not implicitly convert to byte.
>
> Maybe not, but casting back and forth between them is ugly. Pascal works
> this way, and it was one of the things I wound up hating about Pascal,
> all those ORD and CHR casts.
>
> A reasonable case could be made for getting rid of all implicit
> conversions. But those are there for a reason - it makes writing code
> more natural and easy. It allows generic code to work without special
> casing. And the cost of it is sometimes you might make a mistake.

In my experience, relatively little code needs to do arithmetic on
characters. Some definitely does, but far more code does not, and that code
ends up with bugs far too often because of integral types converting to
characters. That's particularly true when stuff like string concatenation
gets involved. I don't know how big a deal it is that characters can
implicitly convert to integral types, and maybe that's okay, but I'm quite
convinced that having integral types implicitly convert to characters was a
mistake.

And as for generic code, my experience is that implicit conversions are an
utter disaster there. It's way too easy to do something like have is(T : U)
in your template constraint and have the code work great with a U but fail
with types that implicitly convert to U. Ideally, all conversions would be
done before the function is called, and if not, the conversion needs to be
forced internally. Otherwise, you either get compilation errors with types
that implicitly convert, or you get subtle bugs.

There are times when implicit conversions can be really nice, but IMHO, they
have no business in generic code.

Also, the fact that (u)bytes and (u)shorts get promoted to (u)ints with
arithmetic is the sort of thing that does not play at all nicely with
generic code. That doesn't necessarily mean that it's a mistake for them to
work that way, but it is a case where you're likely going to be forced to
use explicit casts in generic code just to make those smaller integral types
work when the code would work just fine for other types without the casts.

So, I really don't see arguments with regards to the implicit conversion of
integral types to characters in generic code as holding much water given
what we're doing with the smaller integral types and how the implicit
conversion to character types is something that seems to keep resulting in
folks posting about bugs caused by them in D.Learn - especially when string
appending and concatenation get involved. Pretty much no one wants something
like str ~= 0 to work, but it does, and particularly when you start throwing
in stuff like the ternary operator, folks screw up and end up appending
integers to strings.

- Jonathan M Davis



More information about the Digitalmars-d mailing list