Microsoft KB Archive/129803

= INFO: Variable Coercion Rules in Visual Basic =

Article ID: 129803

Article Last Modified on 5/6/2003

-

APPLIES TO


 * Microsoft Visual Basic 5.0 Learning Edition
 * Microsoft Visual Basic 6.0 Learning Edition
 * Microsoft Visual Basic 5.0 Professional Edition
 * Microsoft Visual Basic 6.0 Professional Edition
 * Microsoft Visual Basic 5.0 Enterprise Edition
 * Microsoft Visual Basic 6.0 Enterprise Edition
 * Microsoft Visual Basic 4.0 Standard Edition
 * Microsoft Visual Basic 4.0 Professional Edition
 * Microsoft Visual Basic 4.0 Professional Edition
 * Microsoft Visual Basic 4.0 16-bit Enterprise Edition
 * Microsoft Visual Basic 4.0 32-Bit Enterprise Edition

-



This article was previously published under Q129803



SUMMARY
When two or more variables of different types are involved in an expression, Visual Basic uses a set of internal type coercion rules to change the different types into a single type. For every combination of input and result types, there is a specific coercion rule. (Contrary to some speculation, Variants are not involved.) This makes Visual Basic faster and more efficient, but it can produce some puzzling results if you aren't aware of what Visual Basic is doing behind the scenes. This article lays out some of the less obvious conversion rules, their benefits, and some possible scenarios where this can lead to unexpected results.



MORE INFORMATION
Coercion between numeric types is pretty straightforward. Smaller types (integer) coerced to larger types (double) simply have their value assigned. Larger types (double) coerced to smaller types (integer) have their value assigned, but generate an Overflow error if the smaller type cannot contain the larger type's value. Other coercion rules are not as obvious.

NOTE: Any type can be implicitly coerced to any other type (excluding objects).   Source Type    Coerced to      Apply this rule --

Integer       Boolean         0=False, non-zero=True

Boolean       Byte            False=0, True=255

Boolean       any numeric     False=0, True=-1 (except Byte)

String        Date            String is analyzed for mm/dd/yy, and so on

Date          numeric type    Coerce to Double and use DateSerial(Double)

numeric type  Date            Use number as serial date, check valid date range

numeric type  Byte            Error if negative

String        numeric type    Strings are treated as a Double when they need to represent a                                 number Some of these rules allow for simplified syntax when writing your code. For example:   ReturnCode% = FunctionThatReturnsAnInteger If (ReturnCode%) Then ... This piece of code takes advantage of the implicit Integer to Boolean coercion and correctly evaluates the expression in the If statement.

Note on Strings as Numbers
Treating Strings as Doubles when they need to represent a number gives the String the maximum possible range and nearly the best possible precision (only Currency can have more precision, at a sacrifice in range). Because these coercions are generated by the compiler, the rule must be decided up front without regard to the actual content of the string.

Note that "treating as Double" is not quite the same as "coercing to Double." For example, addition and subtraction operators treat Currency as a preferable type to Double. Currency plus String will be treated as Currency plus Double, which would use Currency addition. Thus the string will be coerced directly to Currency.

Why Use Coercion Rules?
The largest reason is performance. Hard-coded coercion rules make Visual Basic version 4.0 faster and more efficient and provide backward compatibility to previous versions of Visual Basic. One of the big speed advantages comes because Visual Basic version 4.0 now knows the data type of control properties. Knowing the type of properties provides trememdous performance advantages. Without it, for example, setting a property required Basic to package the value in a Variant, and the control to unpack and coerce it to the right type. Now the control knows it is receiving the correct specific type, and Basic does a direct coercion to that type without ever involving the overhead of a Variant.

Unexpected Results
The following code pieces show a few common scenarios where errors can be generated by Visual Basic if types and coercion rules are not carefully considered: Dim I As Integer, J As Integer Dim L As Long, M As Long Dim S As String

I = 32767 L = 32767 M = 1 S = "Hello World!"

J = I + 1 ' Overflow. Integer upper limit = 32767. No coercion applied.

J = I + M  ' Overflow. I+M is coerced to a Long and the value 32768 is generated, ' but when the assignment operator is resolved, this Long value is  ' coerced back to Integer (J's type) and overflows.

L = I + 1 ' Overflow. Coercion is not applied until the assignment operator is  ' resolved. I + 1 'Overflow's the temporary Integer variable created ' to resolve the plus operator.

If I Then Print "I is True" If Not I Then Print "Not I is True" ' This prints both 'I is True and Not I is True', a logical ' contradiction. The value of I = 32767, which is non-zero and under ' the Integer to Boolean rule, is coerced to True. With 'Not I', ' the NOT operator is applied first, which produces -32768 which is  ' also non-zero and, therefore, True. The following scenario shows how implicit conversion can generate a variety of unexpected results. You can add this code to a new program and run it too see the output. Private Sub Form_Click Call MySub(1, 23) '<-- Note: passing *numbers*! End Sub

Private Sub MySub (a As String, b As String) Debug.Print "a = "; a,, TypeName(a) Debug.Print "b = "; b,, TypeName(b) Debug.Print "a + b = "; a + b,, TypeName(a + b)     Debug.Print "a + b - 1 ="; a + b - 1, TypeName(a + b - 1) Debug.Print "1 - a + b ="; 1 - a + b, TypeName(1 - a + b)     Debug.Print "a + b + 1 ="; a + b + 1, TypeName(a + b + 1) Debug.Print "1 + a + b ="; 1 + a + b, TypeName(1 + a + b)     Debug.Print "(1 + b) / a ="; (1 + b) / a, TypeName((1 + b) / a)   End Sub The output is:   a = 1             String b = 23           String a + b = 123      String a + b - 1 = 122  Double 1 - a + b = 23   Double a + b + 1 = 124  Double 1 + a + b = 25   Double (1 + b) / a = 24 Double

Keywords: kbinfo KB129803

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.