7

In c# Language Specification, its to be found "Except for the assignment operators, all binary operators are left-associative"

But will it make at difference for Equality operators? == and != ?

Say: bool X,Y,Z ...

return x==Y==z ... and so on?

Wont the result always be the same even if the order of x,y,z ... differs in the return statement, always return the same value? (if the init values of x,y,z is the same obviously)

(x==y)==z Equals to x==(Y==z) and for (x!=y)==z Equals to x!=(Y==z)

Right?

Niklas
  • 1,753
  • 4
  • 16
  • 35
  • X, Y, and Z might not be variables or constants, but instead have side-effects (ie computing values). That could matter yes. – jv42 Dec 12 '11 at 13:07
  • Well in my example i only use - bool local variable, and only the operator == and !=, not &&.. or properties – Niklas Dec 12 '11 at 13:26
  • Yes, in your example, using plain bools, it won't matter. I was only pointing at a reason for this to be included in the spec. – jv42 Dec 12 '11 at 13:34
  • @jv42: No, it does not matter in that case. You are confusing associativity with order of evaluation. Associativity controls the order of evaluation of the *operators* but not the *operands*. The operands are evaluated left to right regardless of the associativity of the operators. – Eric Lippert Dec 12 '11 at 16:07
  • @EricLippert Of course, you're right, I was thinking about short-circuited evaluation, which has nothing to do with this case anyway. Thanks for the expertise :) – jv42 Dec 12 '11 at 16:26

6 Answers6

14

In the C# 4.0 Language Specification, its to be found "Except for the assignment operators, all binary operators are left-associative"

FYI that line is an error. The null coalescing operator is also right-associative -- not that it matters really. See https://stackoverflow.com/a/6269773/88656 for Jon's great analysis of this issue.

Will it make at difference for equality operators == and != operating only on bools?

No. As you correctly note, operator associativity is irrelevant when dealing only with equality operators and only on bools. Though that is an interesting bit of trivia, I'm not sure why it is particularly relevant.

A number of people have answered that it makes a difference because there could be side effects in the operands. These people are wrong; this is an extremely common error. The order in which operands are evaluated has nothing whatsoever to do with the precedence or associativity of the operators. In C, for example, a conforming implementation is allowed to compute side effects in any order. If you say:

x = (A() != B()) == C();
y = D() != (E() == F());

In C then you are guaranteed that D(), E() and F() do not run before A(), B() and C(). But you are not guaranteed that side effects of B() are computed before C(). A(), B() and C() can be executed in any order in C, legally. Operator associativity, whether 'natural' or imposed by parentheses, does not impose any restriction on the order in which side effects may be computed.

The situation is somewhat improved in C#. In C# you are guaranteed that side effects of operands are observed to happen left to right regardless of the precedence or associativity of the operators. That is, if you have A() + B() * C() then you are guaranteed that A() happens before B() and that B() happens before C(), regardless of the fact that A() is involved in an addition which is lower precedence than a multiplication.

Operator precedence and associativity controls the order in which the operators run, not the order in which the operands are computed.

Community
  • 1
  • 1
Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • 1
    It does still matter more generally, since `someBool == someInt0 == someInt1` and `someInt0 == someInt1 == someBool` differ only in the order of the operands, but only the latter is valid. – Jon Hanna Dec 12 '11 at 20:45
8
bool x = false;
int y = 0;
int z = 1;

Console.WriteLine(x == y == z);//won't compile
Console.WriteLine(y == z == x);//will compile

All down to the associativity of ==.

Jon Hanna
  • 110,372
  • 10
  • 146
  • 251
  • good example ! (in my example all where bools, but illuminating) – Niklas Dec 12 '11 at 14:51
  • 1
    Yes, for this sort of thing it doesn't matter how many cases we find where it doesn't matter, as long as we can find one where it does. – Jon Hanna Dec 12 '11 at 15:04
5

In your example, it would matter. x==y==z would mean "Z is a bool, and the line will return true if 'x==y && z==true' or if 'x!=y && z==false'".

So yes, it matters.

Tipx
  • 7,367
  • 4
  • 37
  • 59
  • Well in my example i only use - bool local variable, and only the operator == and !=, not &&.. or properties – Niklas Dec 12 '11 at 13:25
  • Yes, but Tipx's answer explains how it is the same boolean algebra as the version with != and && that they give. – Jon Hanna Dec 12 '11 at 14:03
  • 1
    Still, for all values of x, y and z where they are bools, then ((x == y) == z) == (x == (y == z)). That said, x **could** be a property that depends on z, or they might not be all bools, or other cases where the associativity is important. It being unimportant in one particular case is, well, unimportant. – Jon Hanna Dec 12 '11 at 14:10
  • 2
    What does the fact that some operands have side effects have to do with it? The side effects will occur in order from left to right; remember, **precedence and associativity has nothing whatsoever to do with the order that the operands are evaluated in**. Precedence and associativity controls the order that the *operators* are evaluated in; the *operands* are evaluated left to right. – Eric Lippert Dec 12 '11 at 16:03
  • @EricLippert: My bad, I figured the associativity and the order of resolution / evaluation were linked. I'll edit this part of the answer out. Thanks for pointing this out, I'll read on the subject later. – Tipx Dec 12 '11 at 16:55
  • Yep, side-effects are irrelevant. Type is still relevant though. – Jon Hanna Dec 13 '11 at 09:50
1

Think of it as (x ^ y ^ z) and you will have your answer.

  • true ^ true ^ true is true no matter the name of the variables carrying the bool values. the same is for true ^ false ^ true result. –  Dec 12 '11 at 13:31
  • 1
    How does this answer the question about why associativity matters? – Jon Hanna Dec 12 '11 at 15:04
  • No problem. An answer out of the scope as you defined it in your question may always be better. You asked for booleans (or same type variables). Am I wrong? –  Dec 12 '11 at 15:44
0

The result will be the same. The associativity of == and != does not matter, but an associativity must be chosen.

Mike
  • 970
  • 8
  • 13
  • 1
    what about side-effects of the evaluation? – Stefan Paul Noack Dec 12 '11 at 13:14
  • @noah1989: OK, *what about them*? Explain what you mean. – Eric Lippert Dec 12 '11 at 16:04
  • The operands of the == operator can be function calls or property getters. If they do change the value of a variable or do something else that changes any kind of state (write to / read from a file, network etc.) this is called a side effect. The order of evaluation becomes important when the evaluation of the left side changes any state in such a way that it affects the result of the evaluation of the right side. – Stefan Paul Noack Dec 13 '11 at 08:05
  • @EricLippert But as you correctly pointed out, this has nothing to do with associativity because the order of evaluation is defined as "left to right" in C#. – Stefan Paul Noack Dec 13 '11 at 08:29
0

It could potentially make a difference if you provided an overload for the equality operator that had side effects. A terrible and pointless idea, obviously, but possible.

luksan
  • 7,661
  • 3
  • 36
  • 38