Functionality problems

Code review rules

Functionality problems concern the users of your software. This is where it really pays off to scan your application with Project Analyzer's problem detection feature. When you fix these issues before finishing your project the users will find your program working better than what it would've been without the fixes.

Most of the functionality problems are related to user interface issues, error trapping and event handling.

General functionality

Stop/End statement found. Your program ends here. Check if you really want to end your program like this. It may be completely as you planned, though, and if you think everything is OK, leave it as is. END, STOP

Error handler missing. A procedure has no error handler. Your program may crash if a run-time error occurs in this procedure. You can ignore this problem in procedures with less than or equal to x lines of code. Write x in the "Ignore when" textbox in Problem Options. Sub/Function and End Sub/Function lines are counted as code, making an empty procedure or property block have 2 lines. Leave the box empty if you don't wish to have a limit. NO_ERROR_HANDLER

Delayed error handling. A procedure uses delayed error handling (On Error Resume Next, Try without Catch). Run-time errors are handled in the procedure(s) that call this one. This may be completely as you planned, or you may have forgotten to add an error handler (On Error Goto, or Catch in a Try..End Try block). You can ignore this problem in procedures with less than or equal to x lines of code. Write x in the "Ignore when" textbox in Problem Options. Sub and End Sub lines are counted as code, making an empty procedure or property block have 2 lines. Leave the box empty for no limit. DELAYED_ERROR_HANDLING

Consider using Aivosto VB Watch, a tool that ensures proper error handling.

Events not handled. An object variable is declared WithEvents. However, none of the events are handled. NO_EVENTS

RaiseEvent fails via constructor. Event handlers cannot catch an Event that fires during object construction. That is, RaiseEvent has no effect in Sub New or one of the procedures called by Sub New. As an exception, you can raise a Shared Event from a Sub New. A Shared Event is not tied to a specific instance, and raising it through an instance constructor works. As an exception to the exception, Shared Sub New cannot raise a Shared Event. Tip: Handling a Shared Event is not possible with the WithEvents keyword. Use the AddHandler statement. RAISEEVENT_CTOR

Hard-coded path found. A string that looks like a hard-coded path name exists in your program. File access through hard-coded paths will fail if the directory structure changes. This rule catches strings starting with "A:\" to "Z:\". It also reports relative paths in declaring a DLL procedure. In addition, the rule reports relative path names found with the following classic VB file access statements: Open, Name, Kill, Shell, ChDir, MkDir and RmDir. These statements may indicate the assumed directory structure at run-time. It is more flexible to operate with path names relative to the installation directory, for example. Where hard-coded paths are really desired, it is best to define the necessary paths with global constants or in a resource file to allow for easier maintenance. PATH

Assignment to self. An assignment statement seems to set the value of a variable or property to itself without modification. Example: x = x. This is most probably an error. The assignment is either unnecessary or it is incorrect and should be fixed. ASSIGNMENT_TO_SELF

Select Case and conditionals

Case branch(es) missing for Enum. A Select Case statement branches off an Enum value, but it does not contain a Case for every Enum constant. This may indicate missing logic, possibly due to an Enum constant added later. Check to see whether this causes problems when an unhandled Enum value is passed. This rule requires every Enum constant name to be listed in a Case, even if the constants have the same value. Use of the underlying numeric values is not acceptable. Ranges such as Case X To Z are not acceptable either. Listing each individual constant helps prevent breaking existing Select Case blocks if the Enum is later changed or rearranged. To accept Case Else as a default branch, check Ignore when Case Else exists. CASE_MISSING

Case Else missing. A Select Case block is missing its Case Else branch. An unexpected input value can go unhandled. This rule lets you prevent bugs from causing havoc beforehand. You can require each Select Case to have a Case Else just in case an unexpected value comes up. As an exception, Case Else is not required by this rule if existing Case branches cover all theoretically possible input values. Tip: To detect unexpected values while debugging and run the final executable without interruption, add the Debug.Assert False statement in each Case Else that may execute due to an unexpected input value. CASE_ELSE

Case useless. A Case condition will not match any input values. The condition is already covered by an earlier condition or conditions (duplicated Case or totally overlapping range). This warning is also triggered for a never-matching Case x To y, where y is less than x. Note that a Case statement can have multiple conditions separated by commas. This rule reviews each condition separately, so there may be both useful and useless conditions in the same Case statement. See also: Case overlap. CASE_USELESS

Case overlap. A Case condition overlaps an earlier condition. Since previous conditions have priority, this condition will not match all the given values. As an example, Case 1 To 5 and Case 3 To 7 overlap in values 3 to 5. To make the Cases more understandable, rewrite this condition so that overlapping does not occur. Note that a Case statement can have multiple conditions separated by commas. This rule reviews each condition separately, so there may be overlapping and non-overlapping conditions in the same Case statement. See also: Case useless. CASE_OVERLAP

Condition always True or False. A conditional statement always evaluates the same way. This is an unconditional statement, really. It may be a flaw in the code. The rule checks the condition of the following keywords: If, ElseIf, Select, While and Until. Tips: To exclude useless code, use #If False rather than If False. This prevents compilation of dead lines into the executable. To loop eternally, use Do..Loop without either Until or While. COND

DLL procedures

Procedure not found in library. A procedure is declared, the library exists on your system, but there is no such a procedure in the file. You have declared a non-existing procedure or the library file you have is not the required version. If you execute this procedure call on this machine, you will most probably get a run-time error. However, the code may still work on another computer with the correct library version available. This rule requires DLL analysis enabled. Enterprise Edition only. NOT_IN_LIB

Declare contains ordinal number. Declare a Function or Sub with its name, not its number. If the numbering is later changed in the DLL, your program will fail. Only when the function has no name can you use the ordinal number. This problem is triggered when a Declare statement refers to function such as "#1". The problem is ignored if DLL analysis is on and the target DLL procedure has no name. ORDINAL

User Interface issues (VB 3-6)

Form missing Icon. A Form doesn't have an icon that is required. A default icon, generated by VB, will be shown. This problem is available for VB 3-6. NO_ICON

Form missing HelpContextID. Your program uses context-sensitive help (F1), but a Form was found that has no HelpContextID set. This problem is available for VB 3-6. NO_HELPCONTEXTID

Default button missing. A dialog box has CommandButtons but none of them is marked Default. When the user hits Enter, none of the buttons handle it as a Click event. This problem is available for VB 3-6. BUTTONS

Cancel button missing. A dialog box has CommandButtons but none of them is marked Cancel. When the user hits Esc, none of the buttons handle it as a Click event. This problem is available for VB 3-6. BUTTONS

Hotkey conflict. Two or more controls or menu items share a hotkey. For example, there are options &Save and &Search in the same menu. This problem is available for VB 3-6. HOTKEY_CONFLICT, HOTKEYS

Hotkey missing. A control or menu item is missing a hotkey. Checked controls: CommandButton, CheckBox, OptionButton, Frame, Menu. This problem is available for VB 3-6. NO_HOTKEY, HOTKEYS

Resizable Form missing Form_Resize. The Form_Resize event is missing from a Form that users can resize at run-time. Your application may look odd if you don't respond to Resize events. This problem is available for VB 3-6. NO_RESIZE

Error event missing. Every Data control should have the Error event implemented. If you don't do it, Visual Basic only displays a simple error message. It is also important to use an error handler inside the Error event, because if a new error occurs, the Error event fires again. This problem is available for VB 3-6. NO_ERROR

Click event missing. A CommandButton or menu item does not do anything when clicked. This problem is available for VB 3-6. NO_CLICK

Timer event missing. A Timer does not fire an event at defined intervals. This problem is available for VB 3-6. NO_TIMER

Timer interval below 55 ms. The interrupt interval of a Timer control is shorter than 55 ms. Shorter intervals are not supported by VB. This problem is available for VB 3-6. TIMER_INTERVAL

Possibly twisted tab order. The tab order of some controls on a form looks questionable. Take a look at the TabIndex properties of the mentioned controls. The best way to do this is to open the form in VB, select the first control and press the Tab key repeatedly. Generally, the focus should move either right or down. Labels with an access key (& in the caption) should precede the control next to them. A container control should precede any child controls placed within it. An back jump is allowed to move the focus from the bottom of the form to the top-left corner. If the form's RightToLeft property is True, Project Analyzer uses a mirrored rule to require moves either left or down. The twisted tab order detection rules are not foolproof. In some cases, a twisted-looking tab order might be all right. Forms that hide, show or move their controls at run-time are exceptional in that their design-time layout is different from the run-time layout. In that case, this rule may produce a false warning and you should ignore it. This problem is available for VB 3-6. TABORDER

Comment directive

The comment directive parameter for the rules on this page is FUNC.

See also

Problem detection
Code review rules

©Aivosto Oy - Project Analyzer Help Contents