In FreeBasic, IIf (A, B, C)
is equivalent to A ? B : C
in C/C /Java/C#, If (A, B, C)
in VB.NET, and B if A else C
in python. However, in VB6, Office VBA and VB.NET, IIf (A, B, C)
is equivalent to this C code:
bool a = A;
auto b = B;
auto c = C;
a ? b : c;
As a result, IIf
works differently in Visual Basic and FreeBasic. For example,
Dim x As Integer, y As Integer
x = 0
y = IIf (x <> 0, 12 \ x, 0)
works normally in FreeBasic, but will throw an exception in Visual Basic. That is because in Visual Basic this code is equivalent to the following C code:
int x, y;
x = 0;
bool a = (x != 0);
auto b = 12 / x;
auto c = 0;
y = a ? b : c;
In VB.NET, using If
will do the same thing as using IIf
in FreeBasic. For example,
Dim x As Integer, y As Integer
x = 0
y = If (x <> 0, 12 \ x, 0)
in VB.NET will not throw exception.
The question is: Why does IIf (A, B, C)
in VB6/VBA evaluate both B
and C
, not selecting one expression to evaluate depending on the value of expression A
?
CodePudding user response:
IIf
is a function. It works like any other function. It doesn't know anything about the expressions used to generate its arguments; only their values. Any expressions you write in your code to pass to IIf
are evaluated first, just as they would be for any other method call.
VB.NET added an If
operator in 2008. Because it's an operator, it's behaviour is baked into the language and short-circuiting is part of that, just as it is part of the behaviour of the ternary operator (?:
) in C-based languages.
CodePudding user response:
Only the FreeBASIC developers can answer this in the affirmative, but here is some plausible speculation:
VB.NET strives to be backwards-compatible to VBA/VB6. The (non-short-circuiting)
IIf
function already existed in VBA/VB6. Thus, making it short-circuiting would break backwards-compatibility (considerIIf(x, SomeMethodAWithSideEffects(), SomeMethodBWithSideEffects()
). Thus, they opted to create a new operatorIf(...)
instead.¹FreeBASIC, on the other hand, never claimed/tried to be compatible to VBA/VB6, just to QuickBASIC: Consider, for example, their object-oriented features, which have completely different syntax. QuickBASIC never had a
IIf
function, so they could use the keyword with slightly different semantics without having to worry about backwards-compatibility.
Now, the obvious follow-up question is: Why doesn't VBA/VB6's IIf
operator short-circuit? Again, I can only speculate, bit I assume that they made IIf
non short-circuiting for consistency. It would have been surprising for a Basic dialect to have something that looks like a regular function (e.g. IIf(a, b, c)
) suddenly to have short-circuiting behavior. But, again, that's just an educated guess. Unless one of the original developers accidentally sees this question, I'm not sure we're going to get an authoritative answer.
¹ In the first Beta version of the .NET Framework, they changed And
and Or
to be logical short-circuiting operators and introduced new BitAnd
/BitOr
operators for the original VBA/VB6 behavior. They had to revert that change in the RTM version and introduce the new AndAlso
/OrElse
operators instead, to avoid breaking backwards-compatibility.