For Next -- strange things happening!

  1. ‹ Older
  2. 4 months ago

    Alberto D

    Mar 10 Pre-Release Testers, Xojo Pro

    Eric, 135 is less than 256, so it is possible to get 135 out of a max 256.

    Can you post the exact loop that get the overflow issue?

  3. Eric W

    Mar 10 Pre-Release Testers, Xojo Pro
    Edited 4 months ago

    Yes I saw that Alberto - it's 4:17AM here so sorry about that. But the overflow issue seems real.

    For X as uint8 = 0 to 255 dim strAnything as string = "Hello World" next

  4. Alberto D

    Mar 10 Pre-Release Testers, Xojo Pro
    Edited 4 months ago

    Eric, you don't have to be sorry about it, it happens.

    I tested the For Next on macOS and the test run just freeze. If I change to 254 then there is no problem.
    I did a test with uint16 and 0 to 65535 and got the same.

    I don't know much of how Xojo works, do you think that the for next go to that value (255 or 65535) and execute the code inside of it and the problem is when it gets to 'Next' that it tries to go to 256 (or 65536) and those values are not valid? so it goes to 0 again (thank you Andre).

    ETA: just used this code and it works, it looks like the last Next is the problem:

    For X As UInt8 = 0 To 255
      Dim strAnything As String = "Hello World"
      if x = 255 then exit // this way Next will not try to increment X beyond Uint8 limit
    Next

    ETA2: Thank you Andre, good to know.

  5. Andre K

    Mar 10 Pre-Release Testers
    Edited 4 months ago

    The problem is that uint8 can only hold values upto 255, if the uint8 variable = 255 and you add 1 the value becomes 0 again and the next will start the loop all over again.

    In this case you should use a variable with at least 16bits to prevent the problem.

    The real problem is that Xojo doesn't support overflow for integer variables.

  6. Andre K

    Mar 10 Pre-Release Testers
    Edited 4 months ago

    In fact you created an endless loop.

    The moral: if you use an integer as a loopcounter be sure to use the type that can handle the whole range of the loop +1.

  7. Eric W

    Mar 10 Pre-Release Testers, Xojo Pro
    Edited 4 months ago

    The moral: if you use an integer as a loopcounter be sure to use the type that can handle the whole range of the loop.

    Agreed. But there are 256 numbers in a uint8 not 255 so it's counter-intuitive that For x as uint8 = 0 to 255 should be a problem. I do this type of thing often with Do loops after all using the full range of the variable.

    However I am comforted by the fact I haven't gone crazy and that others see it too!

  8. Andre K

    Mar 10 Pre-Release Testers
    Edited 4 months ago

    Right, but the last next will try to increase the value of x but because x is limited to a max of 255 it will go round to zero again.

    In a do loop the check for the value of x is at the end of the loop and as soon the var x is 255 it will not be increased anymore and the loop will end. In that case x will never be asked to take a value higher than that 255.

  9. Eric W

    Mar 10 Pre-Release Testers, Xojo Pro
    Edited 4 months ago

    OK but I don't recall having this problem with For..Next in my VB days nor with Open/Libre Office. It's counter-intuitive which is why I'm heading back to Do loops.

    In my real-world situation the debugger caught the exception but in my example code the test run went into hyperspace like Alberto's mac. That is not a good look since For...Next isn't exactly new, but at least the platforms are consistent!

  10. Andre K

    Mar 10 Pre-Release Testers

    In most programs in VB i have seen the variables were dimmed as integer and that integer has a much bigger range and would never show a problem with ranges from 0 to 255. I have never done anything with Open Office, so i cann't comment on that.

    It could be that do loops are a little bit less efficient because you need extra code to increment the loopcounter yourself, but with this smal range it will hardly be measurable. So there is nothing against using them.

    I tested this on Windows and it shows exactly the same behaviour.

    At least you now know where the problem is and you can be sure you are absolutely not getting crazy. :D

  11. Jason P

    Mar 10 Xojo Inc http://xojo.com/

    This post may help:

    https://forum.xojo.com/17039-what-kind-of-integer-does-it-matter/p1#p141325

  12. Eric W

    Mar 10 Pre-Release Testers, Xojo Pro
    Edited 4 months ago

    Thanks for the link Jason. Although somewhat unintentional, I'm glad the uint data types were included in mainstream Xojo. For me, they are important for allowing interoperability between bitwise, mathematical and string bin() and val(&b 32bit) functions. Otherwise bitwise operations would be much harder to use with signed integers. However in this case I was using uint to catch overflow errors which would not stop execution and could otherwise go unnoticed leading to difficulties in debugging, since signed integers are capable of greater and/or signed negative ranges that my application should not allow or have to deal with. Therefore I think For...Next deserves access to the full range of unsigned integers expressly dimensioned by programmers for counting purposes., so that when dealing with a byte one can use an uint8 loop for example. Until that day comes I'll stick with Do...Loop with counters.

  13. John A

    Mar 11 Pre-Release Testers, Xojo Pro Las Vegas, Nevada

    @Eric W Therefore I think For...Next deserves access to the full range of unsigned integers expressly dimensioned by programmers for counting purposes., so that when dealing with a byte one can use an uint8 loop for example.

    uint8 can hold integers from 0 to 255, which is 256 distinct values.
    It's not big enough to hold a value of 256 (9 bits).
    Start with 0 as the 1st value, counting by 1, the 256th 'value' will be 255.
    The For...Next adds 1 to the counter at the bottom of the loop,
    THEN it checks if the counter is greater than the limit.
    A UInt8 counter will fail (or reset to 0) when it tries to increment to 256.

  14. Eric W

    Mar 11 Pre-Release Testers, Xojo Pro
    Edited 4 months ago

    A UInt8 counter will fail (or reset to 0) when it tries to increment to 256.

    ''
    I would like this to be so but it overflows before incrementing to 255. Please run the example code above to verify this with uint8 counters. Anyway, Do...Loop has no such issue if incrementing at the bottom and one's code is clearer too.

  15. John A

    Mar 11 Pre-Release Testers, Xojo Pro Las Vegas, Nevada

    Running in the debugger, breakpoint on the dim:

    For X as uint8 = 0 to 255
       dim strAnything as string = "Hello World"
    next

    On windows X rolls over to 0 after 255, endless loop.

  16. Eric W

    Mar 11 Pre-Release Testers, Xojo Pro Answer
    Edited 4 months ago

    On windows X rolls over to 0 after 255, endless loop.

    Yes John you are right, this is very yesterday's problem for me, sorry. So picking up the thread, we can put Alberto's code contributed above in the loop to remedy Xojo's uint For...Next

    if x = 255 then exit // this way Next will not try to increment X beyond Uint8 limit

    Which as far as I know is the only For..Next in the known universe to need such remedy. Kind of defeats the purpose of For..Next doesn't it?
    So use Do...Loop with uints instead I say unless one is testing for a condition anyway.

  17. Edward P

    Mar 11 Tampa, FL, USA
    Edited 4 months ago

    @Eric W
    Which as far as I know is the only For..Next in the known universe to need such remedy.

    Are you sure? I tried a small test in C:

    #include <stdio.h>
    #include <stdint.h>
    
    int main(int argc, char **argv) {
    	uint8_t i;
    	for (i = 0; i <= 255; i++) {
    		printf("%d\n", i);
    	}
    	printf("Finally %d\n", i);
    	return 0;
    }

    On my Mac (compiler idents as "Apple LLVM version 9.0.0 (clang-900.0.39.2)"), the loop never ends. If coded as for (i=0; i <256; i++) the compiler throws "warning: comparison of constant 256 with expression of type 'uint8_t' (aka 'unsigned char') is always true."

  18. Julian S

    Mar 12 Pre-Release Testers, Xojo Pro UK
    Edited 4 months ago

    Same thing happens in VS C++, and in VS C# too (gets stuck in loop), although VB does raise an exception due to overflow.

  19. Eric W

    Mar 12 Pre-Release Testers, Xojo Pro
    Edited 4 months ago

    I'm not a C guy but aren't you incrementing before the print statement so that your 0 index has already turned to a 1 in the first loop? In BASIC dialects For 0 starts the first pass of the loop with the index value of 0, For 1 starts the first pass of the loop with the index value of 1. Or am I mistaken about this?

    To quote Xojo's language reference for example :

    By default the counterValue is changed by 1 at the end of each loop (when the Next statement is reached or a Continue is invoked within the loop.

    [Emphasis added]

  20. Edward P

    Mar 12 Tampa, FL, USA
    for (i = 0; i <=255; i++) { printf("%d\n", i); }
    1. Set i to zero.
    2. Test against less-than-or-equal-to 255. If false, exit the loop.
    3. If true, execute the code block within the {} brackets.
    4. At the end of the code block, increment i.
    5. Go to step 2.

    It starts printing at 0, not 1, as i is equal to 0 the first time through.

    But the important thing is what happens when i = 255. Note that i is incremented before the test, so it goes from 255 to 0 before the <=255 test is performed.

  21. Eric W

    Mar 12 Pre-Release Testers, Xojo Pro
    Edited 4 months ago

    When reading your code from left to right it looks like i is incremented after the test but I take your word for it.

    But if in the case of For..Next (not being C/C++) the increment only happens "when the Next statement is reached" - as Xojo's Language Reference puts it - then the test in Xojo must occur after the increment to keep the For...Next rules of the language consistent and in tact; and which increment should not occur if the specified valid range is already exhausted!

    However, using Do...Loop instead of For...Next makes for more explicit code with better control IMHO. And if I were king of the universe I would abolish For...Next which of course Xojo Inc. can't.

or Sign Up to reply!