1

This code compiles successfully, but causes System.OverflowException in Visual Studio 2013 during execution:

Sub Main()
    Dim a As ULong = 14345389830683080345D
    Dim c As ULong = 1

    Dim x As ULong = a And 1 '<-- cause System.OverflowException
    Dim y As ULong = a And c '<-- works well
End Sub

Can you explain me why is this happen? And if a variable has small value (e.g. 5), exception doesn't occur.

P.S. Three most significant bits of a variable are all zeros.

  • The max value of a ULong is `18446744073709551615`, and the bitwise AND does not cause the value to be exceeded. You should change `And 1` to be `And 1D`, since the literal `1` is an integer type. – mbomb007 Mar 03 '15 at 21:06
  • Is there a reason that you are defining `Dim a As ULong` and using a Decimal literal type character on the RHS instead of a `UL`? Info: [Type Characters (Visual Basic)](https://msdn.microsoft.com/en-us/library/s9cz43ek.aspx) – Andrew Morton Mar 03 '15 at 21:19
  • @AndrewMorton: That *is* curious, but won't affect the overflow issue. – Dave Doknjas Mar 03 '15 at 21:23
  • @mbomb007: Actually, to get both statements to behave identically, you should use "1UL" instead of "1D" (the latter types the literal as a decimal and still results in the overflow). – Dave Doknjas Mar 03 '15 at 21:24
  • @DaveDoknjas The idea was to get the OP to see other literal type characters and perhaps have an "Aha!" moment. – Andrew Morton Mar 03 '15 at 21:33
  • @Andrew Morton, no, there is no specific reason for using Decimal literal in declaration of "a", but using "UL" postfix in this case doesn't help. – Dmitriy Zakablukov Mar 04 '15 at 05:24
  • @Dave Doknjas, yes, you right! "1UL" works without exception! But I still don't understand the logic of .NET to rise exception in my case... (see commentary to your answer). – Dmitriy Zakablukov Mar 04 '15 at 05:26

1 Answers1

2

The result of using bitwise 'And' on a ULong and an Integer is 'Long' - this is your first case. The overflow is not happening on assignment, but in the evaluation of the 'And' expression itself - it doesn't fit into a 'Long'. The result on a ULong and ULong is 'ULong' - this is your second case.

The types of these values matters. The literal '1' defaults to 'Integer'.

Btw, an easy way to find the result for these is to set Option Infer On and type some examples in VB, such as "Dim v = 1 And 2", then view the compiler's typing of 'v' by hovering over it.

Dave Doknjas
  • 6,394
  • 1
  • 15
  • 28
  • how can it not fit into 'Long' in the 'And' operation, if "a And 1" is equal to 1? – Dmitriy Zakablukov Mar 04 '15 at 05:19
  • The value of 'a' is too large for a long - VB looks at "a And 1" and determines that this will be a 'Long' - then it tries to perform this operation, but the 'a' alone overflows the temporary 'Long' instance, probably even before the 'And' operation (I've updated my answer to clarify this a bit). – Dave Doknjas Mar 04 '15 at 05:35
  • Using "1UL" solves my problem, thank you. But this error was way too unexpected after C++/C#. – Dmitriy Zakablukov Mar 04 '15 at 05:42
  • @DmitriyZakablukov By default, C++/C# do not perform overflow checks. You can enable overflow/underflow checking in a C# project in the project properties->"Build"->"Advanced". Similarly, you can disable it for a VB project in project properties->"Compile"->"Advanced Compile Options...". – Andrew Morton Mar 04 '15 at 17:46
  • @DmitriyZakablukov There is a table for [Data Types of Operator Results](https://msdn.microsoft.com/en-us/library/ms235255.aspx) - bitwise operators are near the end. – Andrew Morton Mar 04 '15 at 17:47
  • @Dave Doknjas Thank you for your help! My value of "a" indeed doesn't feet in Long type. – Dmitriy Zakablukov Mar 04 '15 at 20:37