On Saturday, April 27, 2013 13:16:55 Walter Bright wrote: > In general, D treats bool, char, wchar, and dchar as integer types. D also > follows the C practice of unadorned integer literals being typed as ints, > and the C practice of default integral promotions. > > If you're not aware of this, yes, you can get surprised when working with > overloads across those types.
Yes, but I honestly think that that's problem too. I think that there's more of an argument for treating characters as integral types than bool, as they really do hold an encoded number internally, but they really aren't treated as integers in general, and I think that treating them as integers implicitly tends to cause problems when conversions come into play. True, it's nice to not have to cast '0' - 42 when assigning it back to a char, but I also don't think that it's all that big a deal for the cast to be required, and I think that allowing things like "foo" ~ 42 is just asking for bugs, particularly when you can easily do something like \u0042 if you actually want a numberic character literal. "foo" ~ true just so happens to be an extreme case of this, as it clearly makes no sense, and if it happens with variables rather than literals, it's not necessarily as obvious that it's happening. We need to be careful with how strongly stuff is typed, because we don't want to require casts everywhere, as that can introduce other types of bugs because casts are so blunt - which is why not requiring casting when converting between int and uint is probably ultimately a good idea - but characters and bool really aren't integral types, even if they do have a relation to them, and I firmly believe that treating them as integral types implicitly causes more bugs than it fixes. > The solution in the antecedent's particular case is to add an overload > foo(int), which will neatly prevent any unadorned integer literals from > being implicitly cast to char or bool or whatever. It's also a good > practice in that unnecessarily promoting ints to longs is a bit of an > efficiency issue. > > [Generally, I'd raise a red flag on any code that only provided foo(bool) > and foo(long) overloads.] Clearly, with how the language currently works, that should raise a red flag, but I think that it's clear that the majority of us would have expected foo(bool) to work with bools, and foo(long) to deal with integral values, allowing you to just have two overloads rather than several. > > However, we are clearly coming from very different points of view > > here. > > Thanks for understanding my point that this is not a right or wrong issue, > but a matter of perspective. It is definitely a matter of perspective, but I also think that it's fairly clear that most people here don't expect bool to be treated as an integral type and don't like the fact that it is. If it's truly an integral type, why have true and false in the first place? Why not just use 1 and 0? It seems like implicit casting is making it so that there's no real difference between them, and C++ introduced a bool type rather than sticking with C's approach in order to be able to distinguish between bools and integers when overloading. We appear to be doing a poor job of that. - Jonathan M Davis