About foreach loops

Timon Gehr timon.gehr at gmx.ch
Wed Jun 15 10:56:04 PDT 2011


Steven Schveighoffer wrote:
> 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

Well, it does make sense but we have to be careful here. If foreach range
statements get less efficient underway, it is not worth it.
I am perfectly fine with foreach(i;0..n){} just being syntactic sugar for for(int
i=0;i<n;i++){}.

Timon


More information about the Digitalmars-d mailing list