FIX: GP Faults from Using IIF with Temporary Strings

Last reviewed: October 30, 1997
Article ID: Q127069
3.00 WINDOWS kbprg kbbuglist

The information in this article applies to:

  • Standard and Professional Editions of Microsoft Visual Basic for Windows, version 3.0

SYMPTOMS

Using the IIF statement may cause a general protection (GP) fault in a range of addresses from 0023:6BB0 to 0023:7DE0 within VBRUN300.DLL or from 004A:68D0 or 004a:7B00 within VB.EXE. This is a subtle bug that may not be encountered and will not occur on a line using the IIF statement. Other GP faults in segment 23 of VBRUN300.DLL are more indicative of calling a DLL incorrectly, such as forgetting to put "byval" on a DLL's string parameter.

CAUSE

The IIF statement does not release string handles for temporary strings used in its arguments. Under certain conditions, this can result in a GP fault occurring at a seemingly random location later in your program. The code below demonstrates the condition where IIF will not release its string handles.

   dim x$
   x$ = "World"
   y$ = "Hello World"
   Label1.Caption = IIf(3 > 1000, "Hello " & x$, Mid$( y$, 1, 5 ) )

The second and third arguments of this statement result in temporary strings being created. This does not, however, cause the GPF. One of two other events must occur for that to happen:
  • If the user allocates a large string and there is not enough contiguous space for it, Visual Basic will attempt to compact the heap, creating a condition in which the GP fault can occur.

    -OR-

  • Upon exit of the procedure the IIF was located in, the heap will be compacted.

Once either condition occurs, the GP fault will not occur until the next temp string is allocated, which just happens to use the string handle used by the IIF statement. Then the GP fault will occur within one of the two address ranges given above.

WORKAROUND

Avoid the use of functions that return Strings within the IIF statement. For example, to avoid the bug, modify the code listed in the CAUSE section of this article to this:

   dim y$, z$
   y$ = "Hello World"
   z$ = "Small World"
   Label1.Caption = IIf(3 > 1000, y$, z$ )

Here's another alternative:

   if 3 > 1000 then
      label1.caption = y$
   else
      label1.caption = z$
   end if

STATUS

This bug was corrected in Microsoft Visual Basic version 4.0 for Windows.


Additional reference words: 3.00 GPF buglist3.00 fixlist4.00
KBCategory: kbprg kbbuglist
KBSubcategory: PrgCtrlsCus
Solution Type : kbfix


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: October 30, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.