VB Quark #4: type literals

Do you know why you can’t write this code in VB:

   Dim x = 123456789.0123456789

Answer: The IDE won’t let you Winking smile

If you try to write that code the IDE will truncate the number, giving :

   Dim x = 123456789.01234567

To include all the decimal places you need to be using the Decimal type. To do this you indicate the constant is of type decimal by adding the suffix D on the end, eg:

   Dim x = 123456789.0123456789D

The reason for this is VB treats numeric literals as of type Double by default if they have a decimal place. If there is no decimal place in the literal then the value is consider to be an Integer (Int32), or if it is too large for an Integer, it’s considered to be a Long (Int64).

If you want the literal as a type other than Double, Integer or Long you need to either convert using CType, CShort, CSng etc, or add a type literal suffix. The following is the complete list for numeric type literal suffixes in VB:

Suffix Type
F Single
R Double
D Decimal
S Int16, Short
I Int32, Integer
L Int64, Long
US UInt16, UShort
UI UInt32, UInteger
UL UInt64, ULong

In case you’re wondering, the “F” for Single is short for "Float”, and the “R” for Double is short for “Real Number”.

Here’s another example of where you should use type literal suffixes. Consider this code :

      Dim i1, i2 As Int16
      i1 = &HF0
      i2 = i1
And &HFF

If you have Option Strict On, the last line will cause a compile time error saying that an implicit conversion from Integer to Short is not allowed. So what is happening here, and why doesn’t the middle line cause the same problem ?

Well the line i1 = &HF0 compiles fine because the constant &HF0 can be evaluated at compile time, so there’s no problem there. The last line however cannot be evaluated because the variable i1 is not a constant. Try it for yourself if you like: change the declaration of i1 to a Const, and you’ll see the last line  compiles fine with Strict On.

Because VB can’t evaluate the variable expression at compile time, it uses the default type for numeric constants : Integer (aka Int32). And because a short can be implicitly widened to Int32, the expression on the right hand side becomes an Int32: hence the error.

In Visual Studio the error correction wizard will suggest converting the entire  expression to an Int16, as such :

      i2 = CShort(i1 And &HFF)

But that’s a runtime conversion that isn’t needed if you declare the &HFF constant with the correct type literal suffix S:

      i2 = i1 And &HFFS

As you can see, the code correction wizard in Visual Studio doesn’t always provide the best syntax to use, so it really is up to you to know the correct literals to use and apply them. 

Oh, you may have also noticed there is no type literal suffix for Byte and SByte. I’ll leave that for yet another quark Smile