Home
Search
 
What's New
Index
Books
Links
Q & A
Newsletter
Banners
 
Feedback
Tip Jar
 
C# Helper...
 
XML RSS Feed
Follow VBHelper on Twitter
 
 
 
MSDN Visual Basic Community
 
 
 
 
TitleFalse * True
Keywordsquick question answer, quiz answer, answer
Categories
 
1. What does this code do?

    This code uses an If statement so the value inside is being evaluated as a Boolean. This value contains two clauses, "(X > 7)" and "Len(user_name)," combined by multiplication.

    Multiplication returns a numeric result so this statement is converting a numeric result into a Boolean value for use in the If statement. Currently in Visual Basic, True has the numeric value -1 and False has the numeric value 0. Note, however, that Visual Basic considers any non-zero value to be True as a Boolean. Thus this statement is really testing whether the result is zero.

    Now look at the two clauses "(X > 7)" and "Len(user_name)." The first checks whether the variable X is greater than 7. This clause is a Boolean test that returns a Boolean value. Multiplication only works on numeric values so the value of this clause must be converted into a Boolean. Because Visual Basic represents True with -1 and False with 0, this clause evaluates to -1 if X > 7 and 0 otherwise.

    The second clause is "Len(user_name)." This is a numeric value giving the length of the string variable user_name.

    Multiplying the values of clauses together gives 0 if either Len(user_name) is zero or if (X > 7) is False. If neither of these conditions holds, the result is some unknown value other than 0.

    Therefore the code tests whether user_name has zero length and X > 7.

2. Is this a good idea?

    No. This code is obscure and unnecessarily confusing.

    It also depends on the fact that Visual Basic considers 0 to be False and any other non-zero value to be True. If this changes in the language at some point, the code will break in an incredibly obscure manner. And lest you think this could never happen, Microsoft tried to change the value of True when it created Visual Basic .NET. As a bone to Visual Basic 6 developers, they backed off and left the value of True alone. That was easier than fixing the bigger problems they had created.

3. Can you think of an alternative?

 
' See if X > 7 and user_name is not blank.
If (X > 7) And (Len(user_name) > 0) Then
    ' Do something ...
End If
 

    This code is easier to read and understand. It uses Boolean operations to combine Boolean values. It doesn't assume that False is 0 and True is non-zero.

    The original tip was proposed because it is faster than using Boolean operators. In an informal test, the tricky solution took about 0.000000264 seconds while the improved version took only 0.000000308 seconds. There is some difference but not enough to justify this confusing code.


    Graham Cottle points out:

    Surely if using .Net the speed will be improved if you use the AndAlso construct?

        ' See if X > 7 and user_name is not blank.
        If (X > 7) AndAlso (Len(user_name) > 0) Then
            ' Do something ...
        End If

    Thus the Len(user_name) > 0 is not evaluated if X <= 7 as that part is already false.

    Put the one most likely to be false first in the construct.


    This is absolutely true because AndAlso provides "short circuit" evaluation. It doesn't evaluate the second expression if it knows from the first that the combined statement must be false. This is different from the And operator which evaluates both expressions whether they are true or not. Visual Basic 6 and earlier only support And. Other languages use short circuit evaluation.

    Using AndAlso changes the way Visual Basic handles functional side effects. For example, consider this code:

        If Function1() And Function2() Then
            ...
        End If

    In this case, both Function1 and Function2 are executed. If these routines have side effects (e.g. they modify global variables), you need to pay extra attention. If you use AndAlso instead of And, Function2 may not execute so its side effects will not occur.

    Of course writing functions with side effects is poor programming practice because it can be very confusing so this should not be an issue. The original developers of Visual Basic felt people would be confused if they used short circuit evaluation and their side effects didn't occur so they made And evaluate all arguments.


    Toby adds:

    Perhaps faster way would be

        If X > 7 Then
            If Len(User_name) > 0 Then
                ...
            End If
        End If

    The second function will not be checked if the first is true. With AND/OR operation both functions are tested whether the first result. This should be changed in VB.NET but it happened same way as Boolean values.

    [This is also true and shows how you can avoid the extra test in Visual Basic 6 and earlier versions.

    Toby points out that this can save a lot of time if the tests are slow, for example, if you invoke functions that use database lookups and comparisons.

    Rod]

Moral

Get it working correctly first. Then optimize only where you know it is necessary. (This is an important theme in my book Bug Proofing Visual Basic).

Most software projects fail because they don't work correctly, not because they are too slow.

Copyright © 1997-2010 Rocky Mountain Computer Consulting, Inc.   All rights reserved.
  Updated