Triple equality expression evaluation
Suppose we have 3 variables and we need to ASSERT that they can either all be equal to -1 or neither can be equal to -1. I wrote the following code:
x := 1;
y := 1;
z := 1;
ASSERT( (x = -1) = (y = -1) = (z = -1) );
I often write this kind of che开发者_JS百科ck, but for two variables. Surprisingly the triple comparison compiled too, but it doesn't work as expected. For (1, 1, 1) values I expect it to evaluate to true. After substitution of variable values and simplification we get:
ASSERT( False = False = False );
and I thought that it should evaluate to True, but it doesn't. So how is this triple comparison evaluated?
First of all, the =
operator is a binary operator: it always works on a pair of values. So there's no such thing as a "triple equality". The compiler will evaluate one pair, and use the result to evaluate the other.
When the compiler sees multiple linked operators, it needs to group them into pairs using what's called the "precedence of operators". It's clear if you think about the basic arithmetic operators we learned in primary school. There's no doubt what: 3+2*4
evaluates to: it's equivalent to 3+(2*4)
. When in doubt, always add the grouping yourself. If you do that, you see your expression is equivalent to:
((False = False) = False)
, and it's obvious it evaluates to:
(True = False)
.
What you probably want is to use the AND
operator and group your initial Assert
like this:
ASSERT(((x = -1) = (y = -1)) and ((y = -1) = (z = -1)))
Then I'd probably either write that expression on multiple lines to make the AND
operator obvious (SQL habit, I know), or rewrite it completely:
Assert (
((x = -1) = (y = -1))
and
((x = -1) = (z = -1))
);
or this variant:
Assert (
((x = -1) and (y = -1) and (z = -1))
or
((x <> -1) and (y <> -1) and (z <> -1))
);
My rule is: if it takes more then 1 second to figure out the precedence of operators, add parentheses.
Comparison is associative: False=False=False is equivalent to (False=False)=False. The first False=False evaluates to True, leading to comparison True=False which in turn is False.
精彩评论