dmd 1.046 and 2.031 releases

Robert Jacques sandford at jhu.edu
Mon Jul 6 23:35:44 PDT 2009


On Tue, 07 Jul 2009 01:48:41 -0400, Andrei Alexandrescu  
<SeeWebsiteForEmail at erdani.org> wrote:

> Robert Jacques wrote:
>> On Mon, 06 Jul 2009 01:05:10 -0400, Walter Bright  
>> <newshound1 at digitalmars.com> wrote:
>>
>>> Something for everyone here.
>>>
>>>
>>> http://www.digitalmars.com/d/1.0/changelog.html
>>> http://ftp.digitalmars.com/dmd.1.046.zip
>>>
>>>
>>> http://www.digitalmars.com/d/2.0/changelog.html
>>> http://ftp.digitalmars.com/dmd.2.031.zip
>>  Thanks for another great release.
>>  Also, I'm not sure if this is a bug or a feature with regard to the  
>> new integer rules:
>>     byte x,y,z;
>>    z = x+y;    // Error: cannot implicitly convert expression  
>> (cast(int)x + cast(int)y) of type int to byte
>>  which makes sense, in that a byte can overflow, but also doesn't make  
>> sense, since integer behaviour is different.
>
> Walter has implemented an ingenious scheme for disallowing narrowing  
> conversions while at the same time minimizing the number of casts  
> required. He hasn't explained it, so I'll sketch an explanation here.
>
> The basic approach is "value range propagation": each expression is  
> associated with a minimum possible value and a maximum possible value.  
> As complex expressions are assembled out of simpler expressions, the  
> ranges are computed and propagated.
>
> For example, this code compiles:
>
> int x = whatever();
> bool y = x & 1;
>
> The compiler figures that the range of x is int.min to int.max, the  
> range of 1 is 1 to 1, and (here's the interesting part), the range of x  
> & 1 is 0 to 1. So it lets the code go through. However, it won't allow  
> this:
>
> int x = whatever();
> bool y = x & 2;
>
> because x & 2 has range between 0 and 2, which won't fit in a bool.
>
> The approach generalizes to arbitrary complex expressions. Now here's  
> the trick though: the value range propagation is local, i.e. all ranges  
> are forgotten beyond one expression. So as soon as you move on to the  
> next statement, the ranges have been forgotten.
>
> Why? Simply put, increased implementation difficulties and increased  
> compiler memory footprint for diminishing returns. Both Walter and I  
> noticed that expression-level value range propagation gets rid of all  
> dangerous cases and the vast majority of required casts. Indeed, his  
> test suite, Phobos, and my own codebase required surprisingly few  
> changes with the new scheme. Moreover, we both discovered bugs due to  
> the new feature, so we're happy with the status quo.
>
> Now consider your code:
>
> byte x,y,z;
> z = x+y;
>
> The first line initializes all values to zero. In an intra-procedural  
> value range propagation, these zeros would be propagated to the next  
> statement, which would range-check. However, in the current approach,  
> the ranges of x, y, and z are forgotten at the first semicolon. Then,  
> x+y has range -byte.min-byte.min up to byte.max+byte.max as far as the  
> type checker knows. That would fit in a short (and by the way I just  
> found a bug with that occasion) but not in a byte.

That's really cool. But I don't think that's actually happening (Or are  
these the bugs you're talking about?):

     byte x,y;
     short z;
     z = x+y;  // Error: cannot implicitly convert expression (cast(int)x +  
cast(int)y) of type int to short

     // Repeat for ubyte, bool, char, wchar and *, -, /

And by that logic shouldn't the following happen?

     int x,y;
     int z;
     z = x+y;  // Error: cannot implicitly convert expression (cast(long)x  
+ cast(long)y) of type long to int

i.e. why the massive inconsistency between byte/short and int/long? (This  
is particularly a pain for generic i.e. templated code)

BTW: this means byte and short are not closed under arithmetic operations,  
which drastically limit their usefulness.


More information about the Digitalmars-d-announce mailing list