I know that logical operators in C follow short circuiting but my doubt is that are short circuiting and operator precedence rules not opposing each other. See the below example :
#include<stdio.h>
int main()
{
int a;
int b=5;
a=0 && --b;
printf("%d %d",a,b);
return 0;
}
According to the precedence rules, the highest precedence is of the prefix operator. So --b
should be evaluated first and then the &&
and at last result will be assigned to a
. So expected output should be 0 4
. But in this case the second operand of &&
never actually executes and result comes out to be 0 5
.
Why precedence rules are not being applied here. Are logical operators exempted from precedence rules? If yes, what other operators show such behavior? And what is the logic behind this behavior?
You're conflating two related but different topics: operator precedence and order of evaluation.
The operator precedence rules dictate how various operators are grouped together. In the case of this expression:
a=0 && --b;
The operators are grouped like this:
a = (0 && (--b));
This has no effect however on which order the operands are evaluated in. The &&
operator in particular dictates that the left operand is evaluated first, and if it evaluates to 0 the right operand is not evaluated.
So in this case the left side of &&
which is 0
is evaluated, and because it is 0 the right side which is --b
is not evaluated, so b
is not incremented.
Here's another example of the difference between operator precedence and order of evaluation.
int val()
{
static x = 2;
x *= 2;
return x;
}
int main()
{
int result = val() + (5 * val());
printf("%d\n", result);
return 0;
}
What will the above program print? As it turns out, there are two possibilities, and both are valid.
In this expression:
val() + (5 * val())
There are no operators that have any type of short circuit behavior. So the compiler is free to evaluate the individual operands of both +
and *
in any order.
If the first instance of val()
is evaluated first, the result will be 4 + ( 5 * 8) == 44
. If the second instance of val()
is evaluated first, the result will be 8 + (5 * 4) == 28
. Again, both are valid since the operands may be evaluated in any order.