Andrei Alexandrescu, el 7 de julio a las 00:48 me escribiste: > Robert Jacques wrote: > >On Mon, 06 Jul 2009 01:05:10 -0400, Walter Bright > ><[email protected]> > >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.
This seems nice. I think it would be nice if this kind of things are commented in the NG before a compiler release, to allow community input and discussion. I think this kind of things are the ones that deserves some kind of RFC (like Python PEPs) like someone suggested a couple of days ago. -- Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/ ---------------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ----------------------------------------------------------------------------
