Runtime error 91 not raised: VB6 object variable silently auto-instantiates on member access
0 reputation · 18 Mar 2025, 17:22 UTC
0 reputation · 18 Mar 2025, 17:22 UTC
In a VB6 Standard EXE project, I have a class module with a default property (marked via the VB_UserMemId attribute). In form code, a variable is declared as Dim obj As MyClass and a member is accessed immediately, without any Set obj = New MyClass. Instead of raising runtime error 91 ("Object variable or With block variable not set"), an instance appears to be created silently and the call succeeds.
I want a repeatable development environment where uninitialized object access fails deterministically, so initialization bugs surface during testing rather than being masked. The uncertainty is which conditions cause VB6 to auto-instantiate instead of raising error 91.
The behavior seems to depend on whether the class exposes a default property and whether the call is early-bound or late-bound. The language documentation I have found does not clearly state when auto-instantiation supersedes error 91. Assume VB6 SP6, Option Explicit enabled.
VB6 only auto-instantiates an object variable when it is declared with the As New syntax (Dim obj As New MyClass). A plain Dim obj As MyClass without New never auto-instantiates; any member access on a Nothing reference raises runtime error 91. This rule applies identically to early-bound and late-bound calls, and the presence of a default property (VB_UserMemId = 0) does not alter it.
As New declarator. The compiler emits a hidden If obj Is Nothing Then Set obj = New MyClass guard before every member access on such variables.Dim obj As Object or CallByName on a Nothing reference raises error 91. No silent instantiation occurs.obj.DefaultProp on a Nothing reference raises error 91 regardless of VB_UserMemId.Option Explicit, optimization settings, VB_PredeclaredId, VB_Exposed — none change the error-91 behavior for non-As New variables.If your code shows Dim obj As MyClass but member access succeeds without error 91, one of these is almost certainly true:
As New in the saved file (the VB6 designer sometimes serializes As New while the code window shows As MyClass).As New.With block or generated code path performs an implicit Set before the call.As New declaration; a full clean rebuild (delete *.exp, *.lib, *.obj) is required after editing..frm or .cls file in Notepad and search for As New on the variable name.Debug.Assert obj Is Nothing immediately before the member access; the IDE breaks if the variable is already instantiated.Nothing or an instance pointer.Err.Number at every call site to confirm error 91 is raised.To guarantee uninitialized access fails:
As New in declarations. Use Dim obj As MyClass and explicit Set obj = New MyClass.If obj Is Nothing Then Err.Raise 91As New in variable declarations.Does the variable declaration appear as Dim obj As MyClass in the raw .frm/.cls file (opened in Notepad), or does the file contain Dim obj As New MyClass? This single check determines whether the fix is removing New or investigating a deeper tooling issue.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.