2

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"

Community
  • 1
  • 1
donutguy640
  • 377
  • 1
  • 4
  • 20

1 Answers1

5

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)
Mathieu Guindon
  • 69,817
  • 8
  • 107
  • 235
  • What (in the OP's original code) makes the `Or` *not* a logical operator (though I can't tell if your answer really states that)? Seems like logical vs. bitwise would depend on the types of variable involved ? – Tim Williams Oct 11 '16 at 23:52
  • 2
    @TimWilliams AFAIK that's correct: these operators are *logical* operators when they're involved in a *Boolean expression*, and *bitwise* operators otherwise (with the operands possibly implicitly converted to long integers). Bitwise operations are commonly used to determine whether a flag is "on" when dealing with combined enum values, for example. – Mathieu Guindon Oct 11 '16 at 23:56
  • @TimWilliams actually the distinction between "logical" and "bitwise" operators seems pretty artificial when you consider that `11111111 11111111 11111111 11111111` (aka -1/`True`) `And 0` (aka `False`) gives you 0 either way, and `11111111 11111111 11111111 11111111 Or 0` gives you -1/`True` either way as well: in the end *everything* is bitwise ;-) – Mathieu Guindon Oct 12 '16 at 00:26
  • Yes I thought that would be the logical conclusion of following that path... ;-) – Tim Williams Oct 12 '16 at 00:28
  • 2
    Your answer...makes sense in VB's occasional total-nonsense kind of way that I'm learning to hate O_o idk, hopefully it made sense at the time? Regardless, thank you for clearing it up. – donutguy640 Oct 12 '16 at 02:00
  • 2
    @TimWilliams - It depends on the type of the variable it is being assigned to. There's an implicit cast if a bitwise `Or` result is assigned to a `Boolean`. It doesn't get cast if it's being assigned to a numeric type. – Comintern Oct 12 '16 at 02:04