VBScript Quiz Answers, Part Two
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 aLong!
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.)
Comments
- Anonymous
February 25, 2005
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!) - Anonymous
February 25, 2005
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! - Anonymous
February 25, 2005
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.) - Anonymous
February 25, 2005
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. - Anonymous
February 27, 2005
"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? - Anonymous
February 27, 2005
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) - Anonymous
February 27, 2005
The comment has been removed - Anonymous
March 01, 2005
?!?! VBScript doesn't recognises "as" VBA does... or is there a way?? - Anonymous
March 01, 2005
VBScript reserves "As" as a keyword, but does not implement the "As" operator. - Anonymous
March 01, 2005
So why is this a VBScript Quiz? The example isn't... - Anonymous
March 01, 2005
Sorry, but I am not following your train of thought. - Anonymous
March 01, 2005
The example is my fault -- I was still in regular VB mode... - Anonymous
March 01, 2005
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.)