Home > Net >  Why is the implementation of IIf different in Visual Basic and FreeBasic?
Why is the implementation of IIf different in Visual Basic and FreeBasic?

Time:09-12

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 (consider IIf(x, SomeMethodAWithSideEffects(), SomeMethodBWithSideEffects()). Thus, they opted to create a new operator If(...) 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.

  • Related