About foreach loops

Steven Schveighoffer schveiguy at yahoo.com
Wed Jun 15 10:18:47 PDT 2011


On Wed, 15 Jun 2011 13:09:40 -0400, Timon Gehr <timon.gehr at gmx.ch> wrote:

> Steven Schveighoffer wrote:
>> On Wed, 15 Jun 2011 10:35:33 -0400, Caligo <iteronvexor at gmail.com>  
>> wrote:
>>
>>> You can create a temporary if you like:
>>>
>>>   foreach(i; 0..10){
>>>     int ii = i + 1;
>>>     writeln(ii, " ");
>>>   }
>>>
>>> Which outputs:
>>> 1 2 3 4 5 6 7 8 9 10
>>>
>>>
>>> The problem with trying to "fix" foreach is that it would create
>>> problems of its own.  The following code would not behave correctly:
>>>
>>>   foreach(i; 0..10){
>>>     if(i & 1)
>>>       i += 1;
>>>     writeln(i, " is even.");
>>>   }
>>
>> That code relies on undocumented behavior.  It's likely to fail on some
>> other D compiler.
>>
>> We can't worry about existing code that uses undocumented "features" of
>> dmd.  It's utilizing the knowledge of how D rewrites the foreach
>> statement, not how foreach is documented to work.
>> [snip.]
>
> Actually that *is* exactly as it is documented to work.
> Any code exploiting it relies on documented behavior.
>
> See TDPL p. 74:
>
> foreach(<symbol>; <expression1> .. <expression2>) <statement>
>
> is rewritten to:
>
> {
>     auto __n = <expression2>;
>     auto symbol = true ? <expression1> : <expression2>;
>     for(; <symbol> < __n; ++<symbol>) <statement>
> }
>
> This change would introduce an inconsistency with TDPL.

I think it would be worth it.

In any instance of foreach *except* this one, rebinding the value does not  
change the iteration.  It doesn't fit with all other cases of foreach.

-Steve


More information about the Digitalmars-d mailing list