About foreach loops

KennyTM~ kennytm at gmail.com
Wed Jun 15 11:14:53 PDT 2011


On Jun 16, 11 00:53, Andrei Alexandrescu wrote:
> On 6/15/11 11:51 AM, KennyTM~ wrote:
>> On Jun 15, 11 23:23, Caligo wrote:
>>> On Wed, Jun 15, 2011 at 9:44 AM, KennyTM~<kennytm at gmail.com> wrote:
>>>> On Jun 15, 11 22:35, Caligo 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.");
>>>>> }
>>>>>
>>>>> not to mention all the code that's already using foreach.
>>>>
>>>> If the code rely on the 'implicit ref' behavior of 'i', the code is
>>>> doing it
>>>> wrong. The spec never mentioned what happened when the variable is
>>>> modified
>>>> in a ForeachRangeStatement. I believe it is more sane if modifying
>>>> 'i' is
>>>> disallowed unless 'ref' is used.
>>>>
>>>
>>>
>>> This should be a compile time error:
>>>
>>> foreach(i; 0..10){
>>> i += 1;
>>> write(i, " ");
>>> }
>>>
>>> This should be legal.
>>> foreach(ref i; 0..10){
>>> i += 1;
>>> write(i, " ");
>>> }
>>>
>>> Is that the general consensus here?
>>
>> A simple patch for this:
>>
>> https://github.com/kennytm/dmd/compare/master...const_foreach_range
>
> Does that take care of change through an alias, e.g.
>
> int * p = i;
> ++*p;
>
>
> Andrei


Error: cannot implicitly convert expression (i) of type const(int) to int*



What the patch does is simply rewrite

     foreach (key; lwr .. upr) body;

into

     foreach (auto __iterator1234 = lwr, auto __limit1235 = upr;
              __iterator1234 < __limit1235;
              __iterator1234++)
     {
        const key = __iterator1234;
        body;
     }

so as long as the 'const' system in D has no bug, the compiler can deny 
all unintended mutation in the loop.



More information about the Digitalmars-d mailing list