VBScript Quiz Answers, Part Two

VBScript Quiz Answers, Part Two

  • Comments 13

When you're getting close to shipping a beta for a big product, the dev team is either insanely busy tracking down last-minute issues, or deathly bored. This week was one of the insanely busy weeks! Lots of late nights. It looks like next week should be a little calmer though.

Anyway, on with the quiz answers.

2) Which of the following are Integer, not Long? Why?

(a) w = TypeName(32768)
(b) x = TypeName(32767 + 1)
(c) y = TypeName(-32767-1)
(d) z = TypeName(-32768)

(c) is Integer. The rest are Long.

I actually gave the answer to this one already, here.

The range of a short integer is -32768 to 32767, so it should be clear why (a) and (b) are Long. (c) is a short integer minus a short integer, the result of which fits into a short integer, so it's a short integer.  But (d) is the unary minus operator applied to a long integer, so it's a Long!

Incredibly, (a), (c) and (d) agree with VB6. but (b) throws an overflow error in VB6! VBScript automatically overflows into larger types but VB6 does not. So this is yet another violation of the subset property.

One reader asked if this meant that there were no negative literals in VBScript. Indeed, that is a reasonable interpretation. But in a later question we'll show that it's not quite that simple.

(Incidentally, VBScript and VB.NET both overflow into larger types, but they use different overflow resolution algorithms. That's a subject for another blog though.)

  • I still find it weird that signed literals are split into an expression -- it strikes me that it's more work to evaluate "-32768 [Short] = -1 [Short] * 32768 [Long] = -32768 [Long]" than to just take the -32768 at face value; it involves a multiplication, three scratch "variables", and an implicit typecast as opposed to just a single scratch variable. Is there any deep seated reason for this? (There must be -- you guys are waaaaaay smarter than me. I just can't work out what the reason is. :)

    (If d had been z = TypeName(-1 * 32768) I'd have got it; I guess I should have paid more attention to the previous post!)
  • Make that four scratch "variables" -- when it comes to doing the multiplication it (assumedly) recasts the -1 as a long and ditches the original short:

    -32768 [Short] = (-1 [Short]) [Long] * 32768 [Long] = -32786 [Long]

    Note to self: never attempt to write a compiler or interpreter!
  • It doesn't take _any_ scratch variables on the script stack. The negation is done in-place.

    Of course, there are local variables and temporaries in the system stack, ie, the stack that the interpreter logic runs on. But the virtual script interpreter stack just pushes the constant and negates it in-place.

    There is also no fancy casting logic. The negation operator has a special case for VT_I2 set to 32768 (and VT_I4 set to 2147483648 -- which goes to R8.)
  • From a compiler perspective, you have two tokens: the '-' sign and the numeric literal. If you want to recognize something like "-1234" as one token, you would end up handling "-1234" and "- 1234" differently which provides no optimization but introduces another opportunity for a bug.
  • "But (d) is the unary minus operator applied to a long integer, so it's a Long!"

    That's.....just wrong. Do you not have the negation sign in VBScript?
  • Sebastian: That makes sense!

    However (not being one to stop asking stupid questions) if you can recognize "-1234" and "- 1234" as being "the same" why not treat "x - 1234" as "x + -1234" and treat "-1234" as a token?

    In the following example you'll end up with an implicit cast in both subtractions; treating "-32768" and "- 32768" as a short would seem to be A Good Idea (although optimising for an edge case like this is probably a total waste of time).

    Dim x As Short, y As Short
    x = 0 : y = 0
    ' Subtract a long from a short
    x = x - 32768
    ' Add a "long short" to a short
    y = y + (-32768)
  • (Just for clarity in case you have your browser at an unfortunate width, the second of each pair of numbers in quotes is "-[space]number" -- it's not particularly clear if the line happens to break in an awkward place. Oh to be able to use some simple formatting in the comments...)
  • ?!?! VBScript doesn't recognises "as" VBA does... or is there a way??
  • VBScript reserves "As" as a keyword, but does not implement the "As" operator.
  • So why is this a VBScript Quiz? The example isn't...
  • Sorry, but I am not following your train of thought.
  • The example is my fault -- I was still in regular VB mode...
  • I think Mat was trying to call out the distinction between VBScript and VB.

    (And of course, "As" is not an operator. There's me, typing faster than I'm thinking again.)
Page 1 of 1 (13 items)