six demon bag

Wind, fire, all that kind of thing!

2015-01-17

Dim var() Considered Harmful

VBScript arrays can be created with fixed or dynamic size. Fixed size arrays are rather straightforward. Define Dim var(4) and you have an array variable var with 5 elements (indexes 0 through 4). Unfortunately dynamic arrays aren't quite as simple.


According to the documentation the official way to create a dynamic array is to use a Dim statement with empty parentheses:

You can also use the Dim statement with empty parentheses to declare a dynamic array.

which does create a variable of the type Variant() as you'd expect:

>>> Dim var()
>>> WScript.Echo TypeName(var)
Variant()

So, everything is good, isn't it?

Well, actually no. The problem with this variable is, that it claims to be an array (type Variant()), but doesn't actually behave like one, because it doesn't have an actual size:

>>> Dim var()
>>> WScript.Echo TypeName(var)
Variant()
>>> WScript.Echo UBound(var)
Subscript out of range (0x9)

It must be resized with ReDim before it can actually be used:

>>> Dim var()
>>> ReDim var(4)
>>> WScript.Echo UBound(var)
4

However, instead of creating something that is almost like an array and then fixing it up, you could just as well use ReDim right away to directly create an array with an actual size (e.g. -1, which is the "size" of an empty array):

>>> ReDim var2(-1)
>>> WScript.Echo TypeName(var2)
Variant()
>>> WScript.Echo UBound(var2)
-1
>>> ReDim var2(4)
>>> WScript.Echo UBound(var2)
4

Some people may argue that defining an array via ReDim defeats the purpose of Option Explicit, because the interpreter will happily create a new variable with any given (mistyped) name. However, that would happen anyway, even if the (correctly typed) variable had been Dimed first.

The only situation where ReDim would raise an error on a mistyped variable is when it's used in combination with the Preserve keyword. That's because that keyword instructs the interpreter to create a new array with the given size, copy all values from the existing array to the new one, and then replace the old array with it. This will obviously fail when there is no existing array variable to copy things from.

This single edge case is not enough to justify the potential issues caused by partial array initialization. Not in my book at least.

So, if you need to create a dynamic array: always use ReDim var(-1).

Posted 18:26 [permalink]