views:

87

answers:

4

If I have the following ...

a OrElse b 

... and a is True then clearly b is never evaluated. But if I add an Or, then what?

a OrElse b Or c

Does/should c get evaluated? And what if I put in some brackets?

Apologies if this is basic. Of course I can test for the answer myself but I can't find this question answered here or elsewhere. Lots of questions dealing with Or versus OrElse but nothing dealing with Or with OrElse

+5  A: 

OrElse short circuits between the left and right side parameters (only 2 parameters). So I would say that C will always be evaluated as you could treat this as (A OrElse B) Or C.

MSDN OrElse

msarchet
A: 

In my personal experience VB tends to obtain the value for all of them regardless of whether they be actually evaulated or not.

This is only helpfull when order matters for items existance and the like. Just wanted to note it.

Cericme
Short circuit and orelse http://visualbasic.about.com/od/quicktips/qt/vbnetlogop.htm
diadem
+3  A: 

In the case presented, c is evaluated. A small test will tell you:

Debug.WriteLine(test(1) OrElse test(2) Or test(3))

Function test(ByVal a As Integer) As Boolean

    Debug.WriteLine(a)
    Return True

End Function

The above example outputs:

1
3
True
Anax
+1 for testing it.
Joel Etherton
+3  A: 

This is an operator precedence problem. The relevant documentation is here:
http://msdn.microsoft.com/en-us/library/fw84t893.aspx?ppud=4

The important excerpts:

  • Operators with equal precedence are evaluated left to right in the order in which they appear in the expression.

and

Inclusive disjunction (Or, OrElse)

So what we learn here is that Or and OrElse have the same precedence and that operators with the same precedence are evaluated from left to right.

Therefore, I would expect that in cases where a is true, b is not evaluated. However, c still will be. In cases where a is false, b is evaluated and regardless of the b's value the Or operator will evaluate c. So, yes, c is always evaluated.

As a practical matter, you should generally prefer OrElse in your code unless you have a good reason to use Or. Or exists now mainly for backwards compatibility.

Joel Coehoorn
I'm a bit puzzled, given that, according to the documentation, `And` has higher precedence that `Or`/`Orelse`. Still, in my program when I used `test(1) OrElse test(2) And test(3)` I get `1` and `true` as output. Any idea?
Anax
@Anax this is being evaluated as such test(1) OrElse resultofAnd
msarchet
@Anax Not sure. I would expect `2,3,1,true` from that. I suspect that it's jitter optimization of some kind.
Joel Coehoorn
@msarchet - yes, but it has to compute the `resultofAnd` first because of `And`'s higher precedence, and that should cause it to output 2 and 3 prior to the 1.
Joel Coehoorn
@Joel: Yeah, that was what I thought as well.
Anax
@Joel Coehoorn I agree that it's probably a JIT optimization somewhere then
msarchet
@Joel @Anax Have I misunderstood something? If the `test(x)` function outputs `x` and returns `True` then `test(1) OrElse test(2) And test(3)` will always output just `1` and evaluate to `true`. From [the OrElse documentation](http://msdn.microsoft.com/en-us/library/ea1sssb2(v=VS.100).aspx) "If the first expression is True, the second is not evaluated". Are you supposing that using an expression as the second operand to `OrElse` must cause the second operand to be evaluated before the first operand? That would be rather bizarre. It seems to me it would make `OrElse` rather useless!
MarkJ
@MarkJ - It's a matter of precedence. Because `And` has higher precedence, it should be as if the full expression were written like this: `test(1) OrElse (test(2) And test(3))`.
Joel Coehoorn
@Joel Yes indeed, operator precedence means the expression should be **parsed** like this `test(1) OrElse (test(2) And test(3))`. That doesn't *necessarily* determine the **evaluation** sequence. To evaluate `test(2) And test(3)` before `test(1)` would **contradict the specification** for `OrElse`. The compiler can easily parse the expressions for the operands before it finally generates any IL. Then it could generate IL to evaluate `test(1)` first, and then, only if `test(1)` evaluated to False, to evaluate `test(2) And test(3)`. Surely this must be how it works?
MarkJ