For Next -- strange things happening!

  1. 9 months ago

    Eric W

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

    I am writing a quick Linux desktop app and seemingly strange things are happening with For...Next loops.

    For example, the following code is supposed to detect how many times "1" occurs in a string:

    dim intTestCount as integer
    For intIndex as integer = 1 to 256
       if strData.Mid(intIndex, 1) = "1" then
          intTestCount = intTestCount + 1
       end if
    next

    intTestCount then equals 135 which is impossible since (a) the loop can only increment intTestCount to a max of 256 and (b) the strData.len = 256 !

    And another thing. If intIndex in a loop (not the one above) is defined as uint8, with the range being from 0 to 255, the loop overflows with a n exception when it reaches 255. That is to say there seems not to be the full 256 numbers in the range!

    I usually use Do loops with manual counters not For Next loops because very explicit code is cheaper to maintain in the long run. However on this occasion I wanted the code to be brief but have spent a lot of time wrestling with problems with the For Next control structure itself.

    I will go back to Do loops but I want to find out if it is just my dev environment or does anyone else ever see this in the Linux IDE ?

    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.

  2. Anthony C

    10 Mar 2018 Pre-Release Testers, Xojo Pro GraffitiSuite Developer

    What are the contents of strData?

  3. Eric W

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

    Anthony, it's binary string of characters produced from the Bin function: "00100110 etc
    However there can never be more increments in the counter going up by +1 than there are passes in the loop, no matter what the data was in the string.

  4. Anthony C

    10 Mar 2018 Pre-Release Testers, Xojo Pro GraffitiSuite Developer

    OK, then I'm not seeing the issue unless there's a typo here...

    @Eric W intTestCount then equals 135 which is impossible since (a) the loop can only increment intTestCount to a max of 256 and (b) the strData.len = 256 !

  5. Jean-Yves P

    10 Mar 2018 Pre-Release Testers, Xojo Pro Europe (France, Besançon)

    completely normal behavior for me too.

  6. Eric W

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

    OK it's something with my system then. Strange thing is the same kind of code seems to work a couple of dozen lines above in the same routine. But not with the overflow issue.

  7. Alberto D

    10 Mar 2018 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?

  8. Eric W

    10 Mar 2018 Pre-Release Testers, Xojo Pro
    Edited 9 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

  9. Alberto D

    10 Mar 2018 Pre-Release Testers, Xojo Pro
    Edited 9 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.

  10. Andre K

    10 Mar 2018 Pre-Release Testers
    Edited 9 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.

  11. Andre K

    10 Mar 2018 Pre-Release Testers
    Edited 9 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.

  12. Eric W

    10 Mar 2018 Pre-Release Testers, Xojo Pro
    Edited 9 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!

  13. Andre K

    10 Mar 2018 Pre-Release Testers
    Edited 9 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.

  14. Eric W

    10 Mar 2018 Pre-Release Testers, Xojo Pro
    Edited 9 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!

  15. Andre K

    10 Mar 2018 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

  16. Jason P

    10 Mar 2018 Xojo Inc Texas

    This post may help:

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

  17. Eric W

    10 Mar 2018 Pre-Release Testers, Xojo Pro
    Edited 9 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.

  18. John A

    11 Mar 2018 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.

  19. Eric W

    11 Mar 2018 Pre-Release Testers, Xojo Pro
    Edited 9 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.

  20. John A

    11 Mar 2018 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.

  21. Newer ›

or Sign Up to reply!