Possible bug with loop decrementing

 

There is potentially an issue with decrementing loops whereby the value of an unsigned value can go to -1. It's easy enough to work around though. 

for(ulong r = 2; r >= 0; r--)
{
    PrintFormat("r= %d", r);
    // Workaround MQL5 bug
    if (r==-1)
        break;
    // do stuff
}

Results in:

r= 2

r= 1

r= 0

r= -1


 
Peter Johnson: here is potentially an issue with decrementing loops whereby the value of an unsigned value can go to -1. It's easy enough to work around though. 
for(ulong r = 2; r >= 0; r--)

Results in:

r= 2

r= 1

r= 0

r= -1

  1. It is almost always your code.
          How To Ask Questions The Smart Way. (2004)
              Don't rush to claim that you have found a bug.
          Questions Not To Ask
              My program doesn't work. I think system facility X is broken.

  2. Wrong. The result is r=2, 1, 0, 18446744073709551615 (uLong_max). There are no negative number in unsigned int or unsigned long. r >= 0 is always true. There's how to do unsigned loops.

    for(ulong r = 2; r > 0; ){ --r; …
    
 

The bug is in your code.


r is a unsigned long variable. When r is 0 and gets decremented, since it cannot be lower than 0, it actually turns to be the value ULONG_MAX ( = 18446744073709551615, according to the documentation). This value is bigger than 0, so the loop is never broken when checking if an unsigned value is lower than 0.


On the other side, when you compare r == -1 you are actually converting -1 to an unsigned value, so at this point your are actually saying if(r == ULONG_MAX). Then the loop breaks.


If you are gonna do something like this, do not put on the loop the condition r >= 0, since this will always be true, and just leave the break condition inside the loop body (this is not recommended, though, as it is just unnecessary; just declare r as a signed value).

Reason: