I'm trying to understand what dictates the lifetime of different bits of data; how the VBA interpreter knows it is safe to release the associated memory of a given variable. Here's what I've found so far:
Value types
Simple value types use scope to determine lifetime; e.g. a Long
that is Dim
med inside a Function will hang around until an Exit/End *
statement is hit. At this point the exact mechanism is unclear to me, but I imagine the VBA interpreter keeps a list of all variables in a given scope, and uses VarPtr
and LenB
to release all memory associated with them.
Object types
Objects meanwhile all derive from the IDispatch
interface which is based on the COM IUnknown
interface. As a result, objects use reference counting to determine lifetime. So a variable which holds a reference to an object (basically a LongPtr
) will be overwritten when it falls out of scope (similar to value types), but just before that happens, the VBA interpreter calls IUnknown_Release
on the IUnknown
interface of the object (or more precisely, whatever interface is being held in the variable/With
block).
As such, it is the responsibility of the COM object to clean up and release its own instance memory whenever the reference count drops to zero
Other Reference types
There are other reference types though (that is, types which are not stored as raw data like Doubles and Longs, but instead as pointers to the full data elsewhere). e.g:
- Strings
- Arrays
- UDTs
- Anything passed ByRef
Now since these are not strictly value types, VBA can't just use scope to determine lifetime; let's suppose some function Dim
s an array, which falls out of scope when the function End
s. Well if it is VBA's default behaviour to call SafeArrayDestroy
on the array pointer then the memory would be freed as soon as the variable is out of scope. However what happens if the array is the return value of the function - now VBA can't free the underlying data when the variable is out of scope or things will break. If the array doesn't use reference counting, then how does VBA know to release it or not?
Similarly for the other types - any clue what exactly determines lifetime of these half value half reference types (they all are assigned without the Set
operator so I guess they are not strictly reference types)