Foreach with byte problems

Jonathan M Davis jmdavisProg at gmx.com
Fri Feb 25 13:43:11 PST 2011


On Friday, February 25, 2011 11:37:23 spir wrote:
> On 02/25/2011 07:52 PM, Andrej Mitrovic wrote:
> > So I'd like to print all values storable in a byte in hex representation:
> > 
> > import std.stdio;
> > void main()
> > {
> > 
> >      int counter;
> >      foreach (byte index; byte.min..byte.max)
> >      {
> >      
> >          if (!(counter % 4))
> >          
> >              writeln();
> >          
> >          writef("%#.2x, ", index);
> >          counter++;
> >      
> >      }
> > 
> > }
> > 
> > If you run this, you'll realize that it doesn't print the final 0x7F.
> > This is because in a foreach range literal (is that the correct term?),
> > the left side is inclusive, but the right side isn't.
> > 
> > Hence this will run the foreach from 0 to 9:
> > foreach (index; 0..10) { }
> > 
> > So I figured I'd just add a +1 at the end, but then I get an error:
> >      foreach (byte index; byte.min..byte.max+1)
> >      {
> >      }
> > 
> > Error: cannot implicitly convert expression (128) of type int to
> > byte.
> > 
> > Of course 128 can't fit in a byte. But how am I supposed to print out the
> > last value if the right hand side of a range literal is non-inclusive?
> > 
> > This behavior is kind of odd, don't you think?
> > 
> > byte.max is 127, but due to the way foreach works, the last value
> > assigned to index is 126. If I was allowed to add +1 for RHS, the last
> > value stored to index would be 127 due to the non-inclusive right side,
> > which is completely legal. Yet DMD complains that I'm trying to store
> > 128 to index.
> > 
> > I guess DMD first checks if the value on the RHS of the range literal can
> > fit to a byte before it cuts one off due to the way range literals work.
> > So how do I work around this?
> 
> lol! One more source of fun in using half-open intervals :-)

In the general case, having the first element of an interval be inclusive and the 
last one exclusive is perfect. That's how it works with iterators in C++. That's 
essentially how it works with array indices, since they start with 0 and their 
length is one greater than the last index. It's just plain nice and makes 
checking end conditions cleaner.

However, it is true that in this particular case, it's annoying. Still, in the 
general case, I do believe that it's definitely the right behavior.

- Jonathan M Davis


More information about the Digitalmars-d-learn mailing list