Option Strict

Option Strict

Setting Option Strict to On in your projects can save a lot of time and trouble in tracking down strange errors.

The Visual Studio IDE provides an extensive set of facilities for making the process of creating code simple and fast.  But some of these facilities create a risk of errors in your code.  One example is the implicit conversion between variable types.  The IDE will allow you to enter code that is, strictly speaking, incorrect.  It fixes the error behnd the scenes.  An example is:

Dim A As Integer = 12
Dim B as Double = 6
MsgBox (A * B)

There are two errors in this code.  Firstly, an integer cannot be multiplied by a double (they are different types), and secondly a numeric value (A * B) cannot be displayed in a message box (message boxes display strings, not numbers).

The IDE makes some assumptions about what you really meant by this code, and converts it as if you had actually entered:

Dim A As Integer = 12
Dim B as Double = 6
MsgBox ((CDbl(A) * B).ToString)

That is, the integer A is converted to a double before being multiplied by B, and the result is converted to a string before being displayed in the message box.    .Net can do both these conversions according to carefully defined rules, and it is very likely that the result is exactly what was intended.

But the IDE provides some control over these silent changes to your code.  It allows you to set Option Strict to On, so that you are warned when these conversions are required, and you are given the opportunity to correct the code.  Why would you want to prevent this useful feature of the IDE from fixing these trivial errors automatically and silently?

The reason is that there are cases where this sort of conversion causes logic errors in your code, and because the conversion is not visible as part of your source code, the errors can be very difficult to find and fix.

Here’s an example.   You have a progress bar that you want to update in three stages.  The first stage is to set it to a value of 20%, indicating that the job is one-fifth complete.  Then you want to move it up to 90% as you complete a variable number of intermediate steps.  Then you will set it to 100% complete when the cleanup task is finished.   The only tricky part of this process is calculating the steps needed between 20% and 90%, because that number changes.    This is the first attempt at that code:

StartupTask() 'One fifth of the total
ProgressBar1.Value = 20
'Steps is the number of tasks occurring between 20% and 90% complete
Dim Increment as Single = 70 / Steps '70 is the range (20 to 90)
For I as Integer = 1 to Steps
   Step(I) 'Some part of the progress from 20 to 90
   ProgressBar.Value += Increment
Next I 
'Progress bar should now be at 90
CleanupTask() 'One tenth of the total (90 to 100)
ProgressBar1.Value = 100

 But the code doesn’t work properly.  Immediately before the cleanup task starts, the progress bar is not at 90%.   It should be at 90% because you initially moved it to 20%, then added enough increments to bring it to exactly 90.  What went wrong?  

The answer is that the Value property of the progress bar is an integer, so that one of you lines of code has been silently changed by the IDE to read

   ProgressBar.Value += CInt(Increment)

That is, your carefully calculated fraction of (70 / Steps) is being rounded up or down each time it is added to the progress bar value.  The rounding is the same each time, so it is additive, and the end result is that the progress bar value is significantly different than 90 when all those intermediate steps have been completed. 

You cannot avoid the conversion from single to integer, but you can avoid having it occur each time, so the error is never more than plus or minus 1.

StartupTask() 'One fifth of the total
ProgressBar1.Value = 20
'Steps is the number of tasks occurring between 20% and 90% complete
Dim Increment as Single = 70 / Steps '70 is the range (20 to 90)
Dim Progress as Single = 20
For I as Integer = 1 to Steps
   Step(I) 'Some part of the progress from 20 to 90
   Progress += Increment
   ProgressBar.Value = CInt(Progress)
Next I 
'Progress bar is now at 90
CleanupTask() 'One tenth of the total (90 to 100)
ProgressBar1.Value = 100

 The rounding is now occurring only when the progress bar is moved to a new value.  The calculation of the new position preserves the full value of the fractional increment, and the progress bar will hit the 90 mark exactly.

By making the conversion explicit, it is possible to identify the problem and adjust the code so that rounding does not affect the result.  This is precisely why the IDE offers you the choice of setting Option Strict to On, and why using that setting can save time and trouble in getting the bugs out of your code.

Advertisements
  1. Leave a comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s