21 August 2018

What’s the difference between ?: and Iif()?

There is a simple answer: none. The conditional ?: is called a ternary operator because it takes three arguments. It is often used as a shortcut for an If – Else statement. The syntax is:

result = condition ? expr1 : expr2

The condition must evaluate to either True or False. If the condition evaluates to True, expr1 is assigned to result. If the condition is False, result becomes the value of expr2. Consequently the data-types of expr1 and expr2 must match the type of result, they are either equal or the types of expr1 and expr1 can be implicitly converted to the type of result. Here is an example of how to use the ternary operator:

Dim number As Int, result As String
number = 1
result = number >= 0 ? "Positive" : "Negative"

This construct replaces the following If-Else statement:

If number >= 0
  result = "Positive"
Else
  result = "Negative"
EndIf

The ?: operator is ‘inlined’, the compiler generates the fastest code possible without calling any function. Nonmatching data types are catched by the compiler.
The If-Else statement generates a little more code, because it contains two assignment statements.

The Iif() function is implemented in exactly the same way as the ?: operator. It generates the exact same inlined code.

result = Iif(number >= 0, "Positive", "Negative")

This results in the same optimized code:

037C04D0: mov     eax,[0x048BC190]  ; number to eax
037C04D5: test    eax,eax
037C04D7: jl      short 0x037C04E0  ; jmp if < 0
037C04D9: mov     eax,0x049205B4    ; address of “Positive”
037C04DE: jmp     short 0x037C04E5  ; goto
037C04E0: mov     eax,0x049205F4    ; address of “Negative”
037C04E5: push    eax               ; address of string
037C04E6: push    0x02A37F90        ; address of result
037C04EB: scall   STOSTRSV          ; store string in result

The disassembly is produced with the new Disassemble Proc feature present in the recent updates of GFA-BASIC.
Note – the compiler setting Branch-Optimizing is set to ‘Normal’, which results in shorter code.