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