The book I use gives associativity of logical operators as right to left, so I expect the result of this code to be 2 2 1 but it is 2 1 1.
int x,y,z;
x=y=z=1;
z=++x||++y||++z;
printf("%d %d %d",x,y,z);
Why is this?
The book I use gives associativity of logical operators as right to left, so I expect the result of this code to be 2 2 1 but it is 2 1 1.
int x,y,z;
x=y=z=1;
z=++x||++y||++z;
printf("%d %d %d",x,y,z);
Why is this?
|| has a short-circuit evaluation requirement. If the first operand is different than 0, then the second operand is not evaluated.
(C11, 6.5.14 Logical OR operator) p4 "If the first operand compares unequal to 0, the second operand is not evaluated."
In your case ++y and ++z are never evaluated.
This is a subtle topic. There are 2 types of ordering; evaluation order and associativity. Now it turns out that for && and || in C, both evaluation and associativity are left-to-right, so your book is wrong. Although the associativity in this case makes no actual difference.
To explain associativity, a || b || c, if || is right-to-left, is seen as a || (b || c). But if || is left-to-right, it is seen as (a || b) || c. Well, both produce the same results in all cases. So the associativity of boolean operators doesn't matter (of course, it does matter for some other operators: (a - b) - c != a - (b - c).
The evaluation order is different; it tells us which order to compare things in after we have applied the implicit brackets from associativity. So with left-to-right evaluation order, a || (b || c) (and (a || b) || c) is evaluated in the order a, then b, then c. With right-to-left, both will be evaluated in order c, b, a.
That means even with right-to-left evaluation, you wouldn't see 2 2 1 but rather 1 1 2. Again regardless of associativity. (edit: actually you would see 1 1 1, because you're setting z to the result of the expression, which is of course true)
Another interesting note is that for most operators, evaluation order actually isn't defined. That means (a ++) - (a ++) is undefined behaviour (thankfully; it would be a nightmare of obfuscation otherwise)
See http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B#Operator_precedence
or for a less wikipedia page, http://www.difranco.net/compsci/C_Operator_Precedence_Table.htm
Also rule 6 here: http://en.cppreference.com/w/cpp/language/eval_order#Rules (I'm sure it's in the standard but I can only find references for C++03, not C)