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
