VBScript Quiz Answers, Part Seven

Before I get into today's entry, a brief editorial comment:

Pestilence is a frickin' pain in the rear. Famine was no problem at all, Rodney didn't touch me once, and Master Kaen fell to my powerful fists, but two Amulets of Life Saving, one Wand of Death and four potions of full healing were insufficient to keep Pestilence at bay. That's the second time Pestilence has ruined a perfectly good ascension. I need to figure out how to take that guy out.

(If you have no idea what I'm talking about, it's probably for the best.)


7) What does this silly program do?

On Error Resume Next
For i = 1 To 1/0
  Print "x" & i & "x"
Print "Done"

(a) prints xx, Done
(b) prints x1x, Done
(c) prints Done
(d) Goes into a loop, producing x1x, x2x, etc.

It does (a).

This illustrates something interesting about the implementation of

For-Next loops. It looks like what ought to happen here is first 1 is assigned to the loop variable, then the limit produces an error. We'd resume into the loop, but then what happens when we get to the bottom and try to compare to the limit?

That's not what happens. In fact, all three parameters -- the beginning, ending and step -- are calculated before the assignment to the loop variable. When the calculation of the limit fails the assignment never happens, so the loop variable keeps whatever value it had before. The loop variable was never initialized, so it's

Empty. Control resumes inside the loop. When we hit the Next statement it detects that the For loop was never initialized correctly, raises the seldom-seen "loop not initialized" error, and resumes outside the loop.

There is no end to the shens you can pull with

On Error Resume Next. It makes programs very hard to reason about.

Comments (9)

  1. asgr says:

    That’s all very well, but WHY does it behave like this?

    People who program VB aren’t going to be concerned about the trivial performance gain when you calculate beginning, ending and step before the loop.

    I’m sure they would rather have either the infinite loop (d) or an error straight away upon encountering the illegal ending.

    Please talk about the thinking BEHIND the design decisions, not just ‘what happens’.

  2. Peter says:

    > I need to figure out how to take that guy out.

    Multiple wands of death and lots of running away is how I’ve usually managed. I hear the Cure Sickness spell works well too, but I’ve never gotten a spell-caster to that point.

    I know what you mean, though. Pestilence makes Death look like a pansy.

  3. tony roth says:

    the on error resume next is a dandy! I don’t use until I’ve figured out every error that its hiding!

  4. Eric Lippert says:

    Re: Shens: internet slang for shennanigans. To "pull shens" is to indulge in shennanigans. To "call shens" is to say that someone is full of it.

    Re: why?: You really think anyone wants an infinite loop in this situation? Infinite loops are badness in script. How do you tell IE to stop running a VBScript with an infinite loop in it?

    Re: Pestilence. yeah, I’ll bring more than one WoD next time.

  5. Jeremy Davis says:

    I should really start playing Nethack instead of ADOM. I don’t know how many scores of characters I’ve been through and I’ve still never even made it to the first orb.

    Maybe if I switch now I’ll be working on ascension in 5 years or so.

  6. Dave says:

    I can see how all three things have to be evaluated before VB can determine whether it should go through even one time. A "1 to 10 step -1" loop doesn’t run but it has to know all three to figure that out.

    Really, try/catch has a lot of the same ambiguities. If you wrap a bunch of statements in a try/catch and an exception occurs, it’s not clear which statements were fully executed and which were not. But at least you get the hint that something went wrong, since you are transported to another part of the code.

    It’s fun to see these code puzzlers, but I wouldn’t want to figure out real-life code that depended on this level of implemementation detail!

  7. Doug says:

    I think that On Error Resume Next is one of the most dangerous statements in VB. If this statement is liberally sprinkled throughout a program, it can be very difficult to debug.

  8. Rick C says:

    I just tried this in XPSP3 and WSH 5.7.  As written, you get no output.  (Actually, it appears you get a blank line, but I’m not positive.)  Removing the on error resume next causes a divide by zero error.

Skip to main content