Thread overview
unsigned int in for loops
Feb 04, 2011
eles
Feb 04, 2011
bearophile
Feb 04, 2011
spir
Feb 04, 2011
Ellery Newcomer
Feb 04, 2011
Jesse Phillips
Feb 04, 2011
Jonathan M Davis
Feb 04, 2011
Ellery Newcomer
February 04, 2011
hi everybody,

recently i was hit by an old-known programming error, using unsigned int in for loops could get into infinite traps:

http://stackoverflow.com/questions/665745/whats-the-best-way-to-do-a-reverse- for-loop-with-an-unsigned-index

so, i D (1 or 2) is counter-attacking in some way (for example, disabling
implicit casting of (-1) to UINT_MAX).

cordially,

eles.

PS i really like being able to use an unsigned int for those loops, both for logical and for programming (large values of the loop index), while still avoiding such traps. thanks.
February 04, 2011
eles:

> so, i D (1 or 2) is counter-attacking in some way (for example, disabling
> implicit casting of (-1) to UINT_MAX).

I don't understand your question very well, but at the moment D is doing nearly nothing to avoid this kind of bugs (I have written probably tens of posts on this topic, with little results).

Bye,
bearophile
February 04, 2011
On 02/04/2011 05:14 PM, eles wrote:
> recently i was hit by an old-known programming error, using unsigned int in for
> loops could get into infinite traps:
>
> http://stackoverflow.com/questions/665745/whats-the-best-way-to-do-a-reverse-
> for-loop-with-an-unsigned-index

Aha! was trapped as well recently.

denis
-- 
_________________
vita es estrany
spir.wikidot.com

February 04, 2011
I think this was the impetus for foreach_reverse, or at least it is one place where it is pretty handy. Don't remember what all there is in D1, but in D2 you could do something like

foreach_reverse(i; 0u .. 10u){
// iterates over 9,8,7 .. 1,0
}

for more complex iterations, I suppose you're stuck with

foreach(i; retro(somerange)){
}

or tired old for loops

On 02/04/2011 10:14 AM, eles wrote:
> hi everybody,
>
> recently i was hit by an old-known programming error, using unsigned int in for
> loops could get into infinite traps:
>
> http://stackoverflow.com/questions/665745/whats-the-best-way-to-do-a-reverse-
> for-loop-with-an-unsigned-index
>
> so, i D (1 or 2) is counter-attacking in some way (for example, disabling
> implicit casting of (-1) to UINT_MAX).
>
> cordially,
>
> eles.
>
> PS i really like being able to use an unsigned int for those loops, both for
> logical and for programming (large values of the loop index), while still
> avoiding such traps. thanks.
February 04, 2011
Ellery Newcomer Wrote:

> I think this was the impetus for foreach_reverse, or at least it is one place where it is pretty handy. Don't remember what all there is in D1, but in D2 you could do something like
> 
> foreach_reverse(i; 0u .. 10u){
> // iterates over 9,8,7 .. 1,0
> }

There was some discussion about removing this... don't remember the conclusion. I believe it is also in D1 though.
February 04, 2011
On Friday 04 February 2011 12:31:06 Jesse Phillips wrote:
> Ellery Newcomer Wrote:
> > I think this was the impetus for foreach_reverse, or at least it is one place where it is pretty handy. Don't remember what all there is in D1, but in D2 you could do something like
> > 
> > foreach_reverse(i; 0u .. 10u){
> > // iterates over 9,8,7 .. 1,0
> > }
> 
> There was some discussion about removing this... don't remember the conclusion. I believe it is also in D1 though.

I thought that foreach_reverse was already gone.

- Jonathan M Davis
February 04, 2011
On 02/04/2011 02:31 PM, Jesse Phillips wrote:
> Ellery Newcomer Wrote:
>
>> I think this was the impetus for foreach_reverse, or at least it is one
>> place where it is pretty handy. Don't remember what all there is in D1,
>> but in D2 you could do something like
>>
>> foreach_reverse(i; 0u .. 10u){
>> // iterates over 9,8,7 .. 1,0
>> }
>
> There was some discussion about removing this... don't remember the conclusion. I believe it is also in D1 though.

the range syntax isn't. but yeah.

personally, I would prefer keeping foreach_reverse as long as dmd isn't capable of optimizing the crap out of the likes of

foreach(i; retro(iota(0u,10u)){
}

wait, wtf?

this code:

import std.stdio;
import std.range;
void main(){
    uint sum;
    foreach_reverse(i; 0u .. 10u){
        sum += i;
    }
    writeln(sum);

}

compiled normally yields:

 80497d4:       55                      push   ebp
 80497d5:       8b ec                   mov    ebp,esp
 80497d7:       83 ec 0c                sub    esp,0xc
 80497da:       31 c0                   xor    eax,eax
 80497dc:       89 45 f4                mov    DWORD PTR [ebp-0xc],eax
 80497df:       89 45 f8                mov    DWORD PTR [ebp-0x8],eax
 80497e2:       c7 45 fc 0a 00 00 00    mov    DWORD PTR [ebp-0x4],0xa
 80497e9:       8b 4d fc                mov    ecx,DWORD PTR [ebp-0x4]
 80497ec:       ff 4d fc                dec    DWORD PTR [ebp-0x4]
 80497ef:       3b 4d f8                cmp    ecx,DWORD PTR [ebp-0x8]
 80497f2:       76 08                   jbe    80497fc <_Dmain+0x28>
 80497f4:       8b 55 fc                mov    edx,DWORD PTR [ebp-0x4]
 80497f7:       01 55 f4                add    DWORD PTR [ebp-0xc],edx
 80497fa:       eb ed                   jmp    80497e9 <_Dmain+0x15>
 80497fc:       8b 45 f4                mov    eax,DWORD PTR [ebp-0xc]
 80497ff:       e8 04 00 00 00          call   8049808 <_D3std5stdio14__T7writelnTkZ7writelnFkZv>
 8049804:       31 c0                   xor    eax,eax
 8049806:       c9                      leave
 8049807:       c3                      ret

this code:
import std.stdio;
import std.range;
void main(){
    uint sum;
    foreach(i; retro(iota(1u,10))){
        sum += i;
    }
    writeln(sum);
}

compiled with -O -inline -release, yields:

 80497d4:	55                   	push   ebp
 80497d5:	8b ec                	mov    ebp,esp
 80497d7:	83 ec 54             	sub    esp,0x54
 80497da:	53                   	push   ebx
 80497db:	8d 45 e8             	lea    eax,[ebp-0x18]
 80497de:	31 db                	xor    ebx,ebx
 80497e0:	56                   	push   esi
 80497e1:	57                   	push   edi
 80497e2:	6a 01                	push   0x1
 80497e4:	6a 0a                	push   0xa
 80497e6:	6a 01                	push   0x1
 80497e8:	89 18                	mov    DWORD PTR [eax],ebx
 80497ea:	89 58 04             	mov    DWORD PTR [eax+0x4],ebx
 80497ed:	89 58 08             	mov    DWORD PTR [eax+0x8],ebx
 80497f0:	e8 af 00 00 00       	call   80498a4 <_D3std5range13__T4IotaTkTkZ4Iota6__ctorMFNckkkZS3std5range13__T4IotaTkTkZ4Iota>
 80497f5:	89 c6                	mov    esi,eax
 80497f7:	8d 7d dc             	lea    edi,[ebp-0x24]
 80497fa:	a5                   	movs   DWORD PTR es:[edi],DWORD PTR ds:[esi]
 80497fb:	a5                   	movs   DWORD PTR es:[edi],DWORD PTR ds:[esi] ; whaaat?
 80497fc:	a5                   	movs   DWORD PTR es:[edi],DWORD PTR ds:[esi] ; whaaat?
 80497fd:	8d 75 dc             	lea    esi,[ebp-0x24]
 8049800:	8d 7d d0             	lea    edi,[ebp-0x30]
 8049803:	a5                   	movs   DWORD PTR es:[edi],DWORD PTR ds:[esi]
 8049804:	a5                   	movs   DWORD PTR es:[edi],DWORD PTR ds:[esi]
 8049805:	a5                   	movs   DWORD PTR es:[edi],DWORD PTR ds:[esi]
 8049806:	8d 75 d0             	lea    esi,[ebp-0x30]
 8049809:	8d 7d c4             	lea    edi,[ebp-0x3c]
 804980c:	a5                   	movs   DWORD PTR es:[edi],DWORD PTR ds:[esi]
 804980d:	a5                   	movs   DWORD PTR es:[edi],DWORD PTR ds:[esi]
 804980e:	a5                   	movs   DWORD PTR es:[edi],DWORD PTR ds:[esi]
 804980f:	8d 75 c4             	lea    esi,[ebp-0x3c]
 8049812:	8d 7d f4             	lea    edi,[ebp-0xc]
 8049815:	a5                   	movs   DWORD PTR es:[edi],DWORD PTR ds:[esi]
 8049816:	a5                   	movs   DWORD PTR es:[edi],DWORD PTR ds:[esi]
 8049817:	a5                   	movs   DWORD PTR es:[edi],DWORD PTR ds:[esi]
 8049818:	8d 75 f4             	lea    esi,[ebp-0xc]
 804981b:	8d 7d b8             	lea    edi,[ebp-0x48]
 804981e:	a5                   	movs   DWORD PTR es:[edi],DWORD PTR ds:[esi]
 804981f:	a5                   	movs   DWORD PTR es:[edi],DWORD PTR ds:[esi]
 8049820:	a5                   	movs   DWORD PTR es:[edi],DWORD PTR ds:[esi]
 8049821:	8d 75 b8             	lea    esi,[ebp-0x48]
 8049824:	8d 7d ac             	lea    edi,[ebp-0x54]
 8049827:	a5                   	movs   DWORD PTR es:[edi],DWORD PTR ds:[esi]
 8049828:	a5                   	movs   DWORD PTR es:[edi],DWORD PTR ds:[esi]
 8049829:	a5                   	movs   DWORD PTR es:[edi],DWORD PTR ds:[esi]
 804982a:	8b 45 ac             	mov    eax,DWORD PTR [ebp-0x54]
 804982d:	3b 45 b0             	cmp    eax,DWORD PTR [ebp-0x50]
 8049830:	74 16                	je     8049848 <_Dmain+0x74>
 8049832:	8b 4d b0             	mov    ecx,DWORD PTR [ebp-0x50]
 8049835:	8b 55 b4             	mov    edx,DWORD PTR [ebp-0x4c]
 8049838:	8b 75 ac             	mov    esi,DWORD PTR [ebp-0x54]
 804983b:	2b 4d b4             	sub    ecx,DWORD PTR [ebp-0x4c]
 804983e:	01 cb                	add    ebx,ecx
 8049840:	29 55 b0             	sub    DWORD PTR [ebp-0x50],edx
 8049843:	3b 75 b0             	cmp    esi,DWORD PTR [ebp-0x50]
 8049846:	75 ea                	jne    8049832 <_Dmain+0x5e>
 8049848:	53                   	push   ebx
 8049849:	b8 44 67 07 08       	mov    eax,0x8076744
 804984e:	6a 0a                	push   0xa
 8049850:	e8 3b 04 00 00       	call   8049c90 <_D3std5stdio4File14__T5writeTkTaZ5writeMFkaZv>
 8049855:	31 c0                	xor    eax,eax
 8049857:	5f                   	pop    edi
 8049858:	5e                   	pop    esi
 8049859:	5b                   	pop    ebx
 804985a:	8b e5                	mov    esp,ebp
 804985c:	5d                   	pop    ebp
 804985d:	c3                   	ret


is it just me, or is flow analysis failing pretty hard here?