Drummy
Drummy

Reputation: 203

VB or VBA For Next loop unexpected behaviour

One of my students wrote this program to count up to 5, which I did not expect to work. I believed the target value of x would be overwritten with 0 when the loop begins, so the loop would either not start or run infinitely. Could someone please tell me what is going on behind the scenes?

Dim x As Integer
x = 5
For x = 0 To x
  MsgBox(x)
Next x

Upvotes: 0

Views: 242

Answers (4)

Drummy
Drummy

Reputation: 203

Thanks for all the comments; I think I have a better understanding now. The idea of 'block scope' was something I heard about many years ago but had completely forgotten. I had a little play with this in VB.NET and wrote 'For j = 1 to x', without explicitly declaring j. I was a little surprised to see this works in VB.NET, even with Option Explicit On. Hence block scope (and implicit block scope declaration) exists in practice - in VB. When I try to do the same in VBA, I get the error message 'Variable not defined'. All variables must be declared at least at procedure level. I presume there must be an extra local 'variable' that the compiler, or interpreter has given me for free, and this resides on the stack.

Upvotes: 0

Hans Passant
Hans Passant

Reputation: 941317

This is documented behavior, the relevant phrase in the MSDN documentation for the For statement:

Changing the value of counter while inside a loop can make it more difficult to read and debug your code. Changing the value of start, end, or step does not affect the iteration values determined when the loop was first entered.

The code generator accomplishes this by actually generating this code:

Dim x As Integer = 5
Dim $temp = x
For x = 0 To $temp
  MsgBox(x)
Next

Important behavior btw, not just to avoid coding accidents. Doing it this way allows the loop to be unrolled, one of the basic optimization strategies employed by the jitter.

Upvotes: 2

ZAT
ZAT

Reputation: 1347

Hope this would help :

'counter i.e. loop control variable x <> end i.e. final value of the counter x

'so start and end gets initialized, then control variable starting to change within that limit.

enter image description here

enter image description here

Upvotes: 0

peterG
peterG

Reputation: 1641

The target value is derived first, before the execution of the loop, and isn't touched thereafter. Compare this modified code; even though y is modified within the loop, its initial value is used as the target:

Module Module1
Sub main()
    Dim x As Integer
    x = 5
    Dim y As Integer
    y = 10

    For x = 0 To y
        MsgBox(x)
        y = y - 1
    Next x

End Sub
End Module

Upvotes: 1

Related Questions