Why lower precedence operator executes first? [duplicate] - c

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Problem with operator precedence
we know that precedence of prefix is greater than "LOGICAL AND" (&&) and precedence of "LOGICAL AND" is greater than "LOGICAL OR" (||).
Below program seems to violate it:
int main()
{
int i=-3,j=2,k=0,m;
m=++i||++j&&++k;
printf("%d %d %d %d",i,j,k,m);
return 0;
}
If precedence of ++ is more than && and || then all prefix should execute first. After this i=-2,j=3,k=1 and then && will execute first.
why output shows : -2 2 0 1 ?
The behavior of the program is also same on ubuntu v12.04.

The && and || operators are "short-circuiting". That is, if the value on the left is FALSE for && or TRUE for || then the expression on the right is not executed (since it's not needed to determine the value of the overall expression).

It's correct because Short-circuiting definition.
m = ++i||++j&&++k
First, left part ++i is always TRUE so now i is -2 and it doesn't execute the right part of expression, the value of j,k don't change.

Related

Confusion about operator precedence in C

I got bit confused by how to interpret the precedence of operators in the following snippet:
int a,b,c,d;
a=b=c=d=1;
a=++b>1 || ++c>1 && ++d>1
The values of a,b,c,d at the end of this code snippet are 1,2,1,1 respectively.
I was trying to decipher what was happening here but to no avail.
I know the precedence of ++ is higher than any other operators so why b,c, and d doesn't equal 2?
According to the result I received, I guess that the expression was evaluated left to right when at the first step b is incremented to 2 therefore ++b>1 is true then because there is a logical OR the answer is returned immediately.
Like if it was : (++b>1) || (++c>1 && ++d>1)
Does operator precedence have any other role other than to group operands together? What does it have to do with the order of execution for example?
The reason is because of Short-circuit evaluation which means that the evaluation will stop as soon as one condition is evaluated true (counting from the left).
This:
a=++b>1 || ++c>1 && ++d>1
is therefore similar to this:
if(++b > 1) {
a = true;
} else if(++c > 1) {
if(++d > 1) {
a = true;
}
}

C: What does if(a<b<c) do? [duplicate]

This question already has answers here:
Comparing a variable to a range of values
(7 answers)
Closed 4 years ago.
why does the following if-statement return 1 (true)?
int main() {
short a = 1;
short b = 5;
short c = 4;
if (a<b<c)
printf("true \n");
else
printf("false \n");
return 0;
}
It is obviously not the same as
if(a<b && b<c)
because this returns false.
Thank you
The relational operators (<, <=, >, >=) are read from left to right (and have the same precedence) as you can see here: Operator precedence. Therefore
a < b
is evaluated first. The result of this evaluation (true or false then) will take part in the next evaluation
(1 or 0) < c
Essentially your code is the same as
if ((a<b)<c)
The < operator has left-to-right associativity. So your expression is parsed as follows:
(a<b)<c
So a<b is first evaluated. Since a is less that b it evaluates to true, i.e. 1. So now you have:
1<c
Since c is 4 this is also true, so the final result is 1.
The a<b statement is equal to true or 1. so we can say a<b or 1 is less than c.
printf(a<b); // result is 1
printf(1 < c) // result is true because 1 is less than 4
So this statement (a<b<c) is true
try online

How the expression evaluates? [duplicate]

This question already has answers here:
Evaluation of C expression
(8 answers)
Why isn't "k" incremented in the statement "m = ++i && ++j || ++k" when "++i&&++j" evaluates to true? [duplicate]
(5 answers)
Closed 8 years ago.
can some one draw the precedence tree for the expression and please explain the side effects..values after the expression evaluation in C.
int i=-3, j=2, k=0, m;
m= ++i || ++j&&++k;
according to me output should be -2 3 1 1 but my gnu c compiler printing is -2 2 0 1?
i want to know how?
Because j won't be evaluated due to short circuit evaluation:
m= ++i || ++j && ++k;
↑
At this stage, m is already evaluated to 1 regardless of the right side of the ||. Why?
Because 1 || anything is 1.
The && and || operators in C short-circuit. This means that if the value of their left hand side is enough to determine the overall value, the right hand side is never evaluated.
Your expression is parsed as (++i) || ((++j)&&(++k)). || short circuits, so after ++i has been evaluated, and its value has been found to be -2 (a true value), no more of the expression is evaluated.

Is order of evaluation gauranteed with short circuit evaluation? [duplicate]

This question already has an answer here:
Logical AND, OR: Is left-to-right evaluation guaranteed?
(1 answer)
Closed 9 years ago.
Is the left part of the && always evaluated before the right part?
I want to know because I'm wondering if I can change
if(i > 0)
if(someFunc(arr[i-1], arr[i]))
//do work
to
if(i > 0 && someFunc(arr[i-1], arr[i]))
or would this cause undefined behaviour if the right side gets evaluated first and arr[0-1]is referenced?
Yes, because of short-circuit behavior of logical && operator, in case of && second expression evaluates only when first is true. Read following:
6.5.13 Logical AND operator
4 Unlike the bitwise binary & operator, the && operator guarantees left-to-right evaluation;
there is a sequence point after the evaluation of the first operand. If the first operand
compares equal to 0, the second operand is not evaluated.
From Is short-circuiting boolean operators mandated in C/C++? And evaluation order?
So if i > 0 is false (for example if i = 0) then result of i > 0 expression will be false, and then second operand someFunc(arr[i-1], arr[i] will not be called (evaluated).
Accordingly, if(i > 0 && someFunc(arr[i-1], arr[i])) is safe to code, but be-careful i - 1 shouldn't be > max index value of arr[]. Really I will prefer this form of if compare to nested if blocks (flat is better then nested).
From #Maroun Maroun's answer "Is there any reason for asking if(1 || Foo())?" Additional information that might help you:
if(a && b) - if a is false, b won't be checked.
if(a && b) - if a is true, b will be checked, because if it's false, the expression will be false.
if(a || b) - if a is true, b won't be checked, because this is true anyway.
if(a || b) - if a is false, b will be checked, because if b is true then it'll be true.
Yes. Order of evaluation for the operators &&, ||, , and ? :(ternary operator) are guaranteed from left to right. A sequence point occurs between the left and right sub-expression of these operands. All the side effects of the left sub-expression of these operators (&&, || and ,) are completed before any access to its right sub-expression.
would this cause undefined behavior if the right side gets evaluated first and arr[0-1] is referenced?
Yes. If that were the case, it would cause undefined behavior. (But it doesn't happen that way, so there won't be any undefined behavior.)

Problem with operator precedence [duplicate]

This question already has answers here:
Why does "++x || ++y && ++z" calculate "++x" first, even though operator "&&" has higher precedence than "||"
(11 answers)
Closed 4 years ago.
The O/p comes out to be x=2,y=1,z=1 which doesnt agree with the operator precedence. I was running this on Turbo c++ compiler:
void main()
{
int x,y,z,q;
x=y=z=1;
q=++x || ++y && ++z;
printf("x=%d y=%d z=%d",x,y,z);
}
Actually the result is in complete accordance with standard C. The logical or operator (||) short circuits after ++x because it evaluates to a non-zero number, so the rest of them are ignored.
So starting at x=1, y=1, z=1, after the short circuit, you get x=2, y=1, z=1.
Operator precedence does not in any way determine the order in which the operators are executed. Operator precedence only defines the grouping between operators and their operands. In your case, operator precedence says that the expression
q = ++x || ++y && ++z
is grouped as
q = ((++x) || ((++y) && (++z)))
The rest has absolutely nothing to do with operator precedence at all.
The rest is determined by the semantics of each specific operator. The top-level operator in this case is ||. The specific property of || operator is that it always evaluates its left-hand side first. And if the left-hand size turns out to be non-zero, then it does not even attempt to evaluate the right-hand side.
This is exactly what happens in your case. The left-hand side is ++x and it evaluates to a non-zero value. This means that your whole expression with the given initial values is functionally equivalent to a mere
q = (++x != 0)
The right-hand side of || operator is not even touched.
x=y=z=1;
Makes all the variables = 1
q=++x || ++y && ++z;
Since ++x makes it = 2 and since it is not zero it stops checking the other conditions because the first one is true.
Thus, x=2, and y and z = 1
Logical && (AND) and || (OR) operators are subject to Short-Circuit.
"Logical operators guarantee evaluation of their operands from left to right. However, they evaluate the smallest number of operands needed to determine the result of the expression. This is called "short-circuit" evaluation."
Thus, for logical operators always evaluated as (no matter || or &&) left to right.
And as previously mentioned, precedence here only determines who takes who.
Then left to right rule;
q = ++x || ++y && ++z;
//ok, lets play by rule, lets see who takes who:
//first pass ++ is badass here (has highest precedence)
//q = (++x) || (++y) && (++z)
//second pass &&'s turn
//q = (++x) || ((++y) && (++z))
//done, let's do left to right evaluation
q = (++x) || rest..
q = (true)|| whatever..
hope that helps more clear.

Resources