dmd 1.046 and 2.031 releases
Stewart Gordon
smjg_1998 at yahoo.com
Fri Jul 17 06:19:24 PDT 2009
BCS wrote:
> Reply to bearophile,
>
>> John C:
>>
>>> Did you not read the change log?
>>> "Implicit integral conversions that could result in loss of
>>> significant bits are no longer allowed."
>> This was the code:
>> ubyte m = (n <= 0 ? 0 : (n >= 255 ? 255 : n));
>> That last n is guaranteed to fit inside an ubyte
<snip>
> I'm going with Steven on this one. Making the legality of code dependent
> on it's semantics is risky because it then ends up with bazaar
> portability issues or requiters that the scope of the semantics analysts
> engine be part of the language spec.
For the record, Nice has a form of automatic downcasting that works
something like this, though not AFAIK on numerical comparisons. To take
an example from
http://nice.sourceforge.net/safety.html#id2488356 :
----------
Component c = ...;
?List<Component> children;
if (c instanceof ContainerComponent)
children = c.getChildren();
else
children = null;
----------
getChildren is a method of ContainerComponent, but not of general
Component. The test performed in the condition of the if statement has
the additional effect of casting c to a ContainerComponent within the if
statement's body. Nice also has nullable and non-nullable types (note
the ?) and, in the same way, it forces you to check that it isn't null
before you try to dereference it.
The principle could be applied to if statements and ?: expressions alike
(as it would appear Nice does), and even && and || expressions. And it
could be extended to arithmetic comparisons. A possible way is to spec
that, if n is an int, and k is a compile-time constant >= 0, then given
n >= k ? expr1 : expr2
any occurrence of n in expr1 is treated as cast(uint) n. And similarly
for the other relational operators and other signed integer types. And
then that, if u is of some unsigned integer type, and k is a
compile-time constant within the range of u's type, then given
u <= k ? expr1 : expr2
any occurrence of u in expr1 is treated as cast to the smallest unsigned
integer type that u will fit into. And similarly for the other
relational operators. Then your example would compile. However,
- if we're going to do this, then for consistency we probably ought to
define all literals to be of the smallest type they'll fit into, and
prefer unsigned over signed, unless overridden with a suffix
- we could go on defining rules like this for more complicated
conditions, and it could get complicated
- I'm not sure if this kind of automatic casting is desirable from a
generic programming POV.
Stewart.
More information about the Digitalmars-d-announce
mailing list