Myzandaran
Myzandaran

Reputation: 3

Why does vb.nets '=' operator evaluate different types this way?

I am confused and cannot find information on the rules for how the '=' operator evaluates in vb.net, specifically when comparing different types.

Dim x as String = "1"
Dim y as Integer = 1
Dim z as Boolean = true

When I compare these types (whilst debugging the program) they evaluate as follows:

x = y (True)
y = z (False)
x = z (True)

Since x = y and x = z I would have expected y = z to be also correct.

I assume there is some conversions going on but I'm unsure of the specifics of how this works; since both CBool(y) and CBool(x) both evaluate as true.

Upvotes: 0

Views: 76

Answers (1)

rskar
rskar

Reputation: 4657

There are two things at play here:

  1. A numeric-and-string situation with various operators (such as =, +, -, *, /, etc.) will get translated into a respective numeric-and-numeric overload. E.g. "1"=1 compiles as CDbl("1")=CDbl(1).

  2. For historic reasons, the Boolean of True is mapped to Integer of -1. Hence True=1 is False; but True=-1 is True.

This numeric-and-string thing can be shutdown via Option Strict On, or put under more granular control via Warning Configuration "Implicit conversion" (of the Project Properties window, Compile tab). Yep, it's strange, other BASICs (such as QBasic or QuickBasic) don't do this, but way back when Visual Basic was being developed (the first generation VBA/VB6, that is) it somehow seemed a good idea at the time. I'd bet it's connected with VBA being the stored procedure language (if you will) of Microsoft Access; translating numeric-and-string to the respective numeric-and-numeric overload certainly happens in the SQL dialects of MS SQL Server, Oracle, and DB2. Give it a try and see for yourself - e.g. in SQL Server:

declare @x varchar(250) = '1',@y int = 1
Select (Case When @x=@y Then 1 Else 0 End)

As for True being -1 when converted to integer, that goes way back to Altair BASIC (https://en.wikipedia.org/wiki/Altair_BASIC). It's a trick to let AND and OR and especially NOT to work as expected for contexts of logical operations (and not bit-wise operations). To clarify, AND/OR/NOT were indeed bit-wise operators - e.g. NOT 1 = -2. So for something like Not True to result as False (which is 0), True has to be -1. Altair BASIC through VBA/VB6 do not have bona fide logical operators - logical operations in them are emulated via bit-wise operations on integers. VB.NET, however, does have bona fide logical operators, but of course care must be taken with integers since it'll do legacy behaviors on them.

The official language reference is at https://github.com/dotnet/vblang/blob/master/spec/README.md. At https://github.com/dotnet/vblang/blob/master/spec/expressions.md, there are grids captioned with "Operation Type" that indicate this behavior - although perhaps to subtly.

Upvotes: 2

Related Questions