if exp1 and exp2 and exp3 then
//something
In Delphi is the order of evaluation exp1, exp2 and exp3 (of course they are all Boolean
) is defined or random?
The order of evaluation is only defined when Boolean Short-Circuit Evaluation is enabled. Then, as the documentation in Complete Versus Short-Circuit Boolean Evaluation explains, evaluation is left to right.
If Boolean Short-Circuit Evaluation is not enabled, the order is undefined. The following code demonstrates this:
{$APPTYPE CONSOLE}
function A: boolean;
begin
Result := True;
Write('A ');
end;
function B: string;
begin
Result := '';
Write('B ');
end;
function C: Integer;
begin
Result := 0;
Write('C ');
end;
begin
{$O+}
Writeln('short circuit on');
{$B-}
if A and (B = '') and (C = 0) then Writeln;
Writeln('short circuit off');
{$B+}
if A and (B = '') and (C = 0) then Writeln;
end.
For the first one, you get printed A B C
, and for the second one you get B A C
.
And that was compiled for Win32 - to make this spicy, and bring home the point of this being Undefined, lets run it on Win64 where we get A B C
in both cases.
You might say: "Ok, but maybe just B was called first but the evaluation of the boolean expression B = ''
is evaluated in the correct order." Let's take a look at the assembler code that gets executed:
if A and (B = '') and (C = 0) then Writeln;
0040B17C 8D45E8 lea eax,[ebp-$18]
0040B17F E864EAFFFF call B
0040B184 837DE800 cmp dword ptr [ebp-$18],$00
0040B188 0F94C3 setz bl
0040B18B E81CEAFFFF call A
0040B190 22D8 and bl,al
0040B192 E891EAFFFF call C
0040B197 85C0 test eax,eax
0040B199 0F94C0 setz al
0040B19C 22D8 and bl,al
Nope:
B
, compare to ''
A
, and
it with the result of the string comparisonC
, compare with 0
, and
it with the result of the previous and
Which translates to (written in left to right order):
((B = '') and A) and (C = 0)
Addendum: Because I saw this mentioned in another answer and discussed in the comments. Parentheses are no solution to force order of evaluation of operands. You can only group operations but the compiler might still decide to evaluate the right operand first.
In the code above there is no way to put any parentheses to get A B C
simply because the compiler flipped the first two operands. It then however executed the operators from left to right and that is something to easily confuse - the question was not whether the first or the second and
was executed first but the order of the boolean expressions - the operands.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With