How is the expression True And -1 evaluated? - vb.net

How come the expression True And -1 evaluates to -1?
I would expect that the second operand (i.e. -1) would be automatically converted to True and the result would be True.
I realize that And is interpreted here as the bit-wise AND-operator. But why would that be the case, when the first operand is boolean and the logic interpretation is possible?

That's how the And Operator is supposed to work. To quote from the documentation:
If the operands consist of one Boolean expression and one numeric expression, Visual Basic converts the Boolean expression to a numeric value (–1 for True and 0 for False) and performs a bitwise operation.
Why does it do that? We can only speculate, but I suspect two reasons:
Backwards compatibility. VB6 and VBA also behave like this.
For logic operations, the new short-circuiting operators AndAlso and OrElse should be used instead. Thus, it makes sense that the legacy operators And and Or are used mainly for the bitwise operations.

Related

Why And operator in vb.net

I always use AndAlso while checking multiple conditions as it doesn't evaluate right side unless left one is true. I don't see any situation where someone would like to evaluate right side even if left one fails. If it was needed then why they didn't include same in C#.
Update:
As accepted answer pointed out that it exists because it is used for bitwise operation, that fine enough but I still think they would have overloaded And operator to serve both purposes and just not created AndAlso. If anyone can pour some light on it, this question is still open :)
They included the same in C#. In C# you can use & (And) or && (AndAlso).
There's no real use case i can imagine for the not short-circuit operator when comparing booleans, but And can be used with numeric values, and it then does a bitwise comparison. That's why it exists. But when comparing boolean types, you'll always be using the short-circuit version.
And is also a bit operator. Here is an example showing a mix of And an AndAlso.
Dim foo? As Integer = 5
If foo.HasValue AndAlso (foo And 1) = 1 AndAlso (foo And 4) = 4 Then
Stop
End If

VBA assignment statement with an OR clause

I've come across some code that looks something like this
If (condition) Then
array(index) = array(index) Or variable
End If
Being unfamiliar with VB, it looks to me like some kind of horrid result of a love affair between an assignment statement and a condition clause.
Functionally, I thought it looked like some kind of ?: ternary operation. I now assume it is, though certainly not in a form I'm used to.
I'm aware that the first branch will assign array(index) to itself, that's essentially how the code I'm working on works. I don't THINK it's relevant to the question, but it kinda weirds me out, and there is often more going on than what I realize with VB.
Not a duplicate of Is there a conditional ternary operator in VB.NET? since that question is asking if there IS one, rather than "what the heck does this mean"
What it's not.
There is no ternary operator in VBA. The closest you get is IIf, which evaluates both true and false expressions (so don't use it when either branch has side-effects!):
IIf({bool-expression}, {value-if-true}, {value-if-false})
So it's not anything like a ternary.
We don't know what's in array(index), but let's assume it's some Long:
array(index) = SomeLongInteger Or variable
What you're looking at is a regular assignment:
foo = 42 Or variable
The runtime is going to assign foo with a value. So first it must compute the right-hand side of the assignment (=) operator:
42 Or Variable
The Or operator is often used as a logical operator in Boolean expressions.
However the above expression isn't a Boolean expression, and the Or operator isn't a logical operator here.
What it is.
It's a bitwise operator (in VB the logical and bitwise operators are the same, which is indeed a bit (pun not intended) confusing). In the assignment foo = 42 Or Variable, foo will take the value of the bitwise comparison of 42 Or Variable.
Debug.Print 42 Or 12 'prints 46
How?
Think in binary. This is 42:
00101010
This is 12:
00001100
Then you bitwise-or the two values (remember your truth tables? True Or True = True; True Or False = True; False Or False = False) and you get this:
00101110
..which is the binary representation for - that's right - 46.
So, array(index) = array(index) Or variable does the following:
Read the value of array(index)
Read the value of variable
Bitwise-Or the two values
Assign the result of that operation back to array(index)

Why does isNumeric(string) crash in a while loop with a compound conditional statement?

Today I was working an in-class project with my students when I ran into this bug.
Imgur Link
Pastebin Link
Basically, decTemperature is a String variable that receives an input from the User. In order to teach data validation, short-circuiting, and loops, we were using the following While loop condtionals to force a valid response:
While IsNumeric(decTemperature) = False Or
Convert.ToDecimal(decTemperature) <= 0.0 Or
Convert.ToDecimal(decTemperature) > 135.0
If the user puts in 'abc', in theory the conditional statement should short circuit before reaching the second part of the conditional statement. I attempted the conditional a number of different ways, but ultimately it would crash in every design.
My assumption on the issue probably links closely to an older question I asked about dealing with data types with explicitly setting Option Strict 'on' (although a quick add of Option Strict On in the above code still crashes). That is to say, decTemperature is being processed in each conditional statement before evaluating.
Whatever the case, what is causing the issue and what would be a better approach that still maintains the concepts (that is forcing a valid response from the user)? I have an idea with using a Boolean data type validResponse and setting it, but that seems to be throwing away short-circuiting as a concept.
Or does not short-circuit. Neither does And
OrElse does short-circuit (as well as AndAlso). See OrElse Operator (Visual Basic)
So it should look like this:
While IsNumeric(decTemperature) = False OrElse _
(Convert.ToDecimal(decTemperature) <= 0.0 OrElse _
Convert.ToDecimal(decTemperature) > 135.0)
I would consider using Decimal.TryParse to test the validity of the input.
If you just use Or then every statement is evaluated in every case. That's what the short circuit operators OrElse and AndAlso are for. If you use OrElse the If statement stops the evaluation after the first true statement is detected (or the first false statement in case of an AndAlso).
So in your case the conversion to decimal would be executed in any case. This is avoided with the short circuit operators.

Which is better for performance? And vs AndAlso

When writing an If statement, I've always used And when needed like:
If 1=1 And 2=2 Then
The only time I ever used AndAlso is if the second condition will error if the first isnt true like:
If Not IsDbNull(Value) AndAlso Value=2 Then
However, recently I've heard that AndAlso is better for performance than And as the second condition is only read when the first is true.
In this case, should I always just use AndAlso?
Yes, AndAlso can be faster than And, because it doesn't evaluate subsequent conditions if an earlier condition proves false.
And is a throwback to earlier versions of Visual Basic.
Most (I hesitate to say all) modern languages use boolean operators that short-circuit conditions that don't strictly need to be evaluated.
e.g. && the and operator for C style languages all perform as AndAlso.
Be careful if you've lots of code that use And and Or, a global search and replace can change existing behaviour, if the second condition involves a function call that has side effects.
I would prefer using AndAlso and OrElse unless you specifically require the functionality provided by And & Or
Coming from a C and C++ background into VB (V5 initially) it was always really annoying that VB's and and or didn't short circuit. So the case where the second expression was dependent on the first was always harder to write.
I wouldn't expect to see much of a performance increase most of the time, unless the second expression has significant overhead, short circuiting operators will avoid executing it and thus speeding things up.
But if that second expression is a significant overhead then I would be concerned about side effects which will only be performed sometimes—this will make future maintenance harder and could make correctness harder to maintain.
When the conditions are also functions:
If functionA() And functionB() Then
...
public shared functionA() As Boolean
IF A is false THEN log -> return true or false
...
public shared functionB() As Boolean
IF B is false THEN log -> return true or false
Using AndAlso here could be the wrong way to go, because then it will only log B when both A and B are false.

When is "Or" better to use than "OrElse"?

Is there any situation where Or is better to use than OrElse?
If not, why don't they just "upgrade" the internal code?
The only reason to use Or is when you want bitwise arithmetic, i.e. you want to manipulate the bits in a number:
Sub SetBit(value As Integer, Bit As Integer)
value = value Or (1 << Bit)
End Sub
This kind is the only case appropriate for Or. In all other cases (i.e. when using Boolean logic), use OrElse.
Despite their similar names, Or and OrElse are semantically quite distinct operations which should not be confused with each other. It just so happens to be that the internal representation of Booleans makes it possible to use bitwise Or to achieve a similar (but not the same) effect to OrElse. (Old versions of BASIC and VB – before .NET – exploited this relationship by only providing an Or operation, no OrElse.)
You should always use OrElse instead of Or, except when doing bit-wise arithmetic.
OrElse is a short-circuiting comparison, meaning it will not evaluate the second clause if the first was true. This is extremely useful, because you will often want clauses which could fail without shortcircuiting (eg. x is nothing OrElse not x.HasSomeProperty).
The reason it is not possible to automatically upgrade all 'Or's as 'OrElse's is because the evaluation of the second clause may be important. For example, I could write "True Or SomeBooleanMethodWhichMightThrowAnEception()". Changing that Or to an OrElse would change the meaning of the program.
Edit: This code is evil; I merely added this answer to indicate that this is possible.
Another case would be to use Or when evaluating expressions that perform some sort of side effect that must occur:
Sub DoSomething()
Dim succeeded As Boolean
succeeded = FirstThing() Or SecondThing() Or ThirdThing()
If succeeded Then
' Do something here
End If
End Sub
In this case FirstThing, SecondThing, and ThirdThing are methods that must be executed as a whole whether any of them fail or not, while accumulating a success value. If you used OrElse then if FirstThing or SecondThing fail, then the operations behind the failing method wouldn't occur.