dmd 1.046 and 2.031 releases

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Tue Jul 7 00:33:24 PDT 2009


Robert Jacques wrote:
> 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 *, -, /

http://d.puremagic.com/issues/show_bug.cgi?id=3147 You may want to add 
to it.

> 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

No. Int remains "special", i.e. arithmetic operations on it don't 
automatically grow to become long.

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

I don't find it a pain. It's a practical decision.

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

I think they shouldn't be closed because they overflow for relatively 
small values.


Andrei


More information about the Digitalmars-d-announce mailing list