How is precedence working in C for this expression - c

I am using C programming modern approach
Precedence for '||' operator is 13 and for increment(prefix) is 2 in table how his code is working
int i = 3, j = 4,k = 5;
printf("\n%d",i < j || ++j < k);
printf("\n%d %d %d",i,j,k);
output:1
3 4 5
Yes it is short-circuit and if left side is 0 then only it will go for right side of OR i found that answer while searching but when this question come what i did was simply go search for precedence table check it and solve it as prefix have high precedence j should increment first as it have highest precedence.
Why it does not follow according to precedence or what is my mistake while trying to solve it? when expression like this are there without braces we should use precedence correct or not?

In an operator precedence table, the lower the number, the more tightly it binds its operands.
The expression i < j || ++j < k can be written as (i < j) || ((++j) < k).
Precedence doesn't tell you the order in which things happen, it tells you how to group things. From (i < j) || ((++j) < k), the operator || evaluates the left side first. If it's true, the right side never gets executed. The fact that ++ has a high precedence doesn't change the behaviour of ||.

Precedence is not order of evaluation. Precedence only determines which expressions go with other expressions and operators, essentially adding implied parentheses.
In this example, operator precedence helps us determine that
i < j || ++j < k
means the same as
(i < j) || ((++j) < k)
Then, the individual operators (sometimes) have rules about the order of evaluation. This expression is a use of the || operator on two subexpressions i < j and ++j < k. So per the || rules, the left operand is evaluated first. If its result is not zero, nothing within the right operand is evaluated at all.

You're confusing the difference between operator precedence and order of evaluation.
Operator precedence dictates which operands the operators are grouped with. Order of evaluation dictates when each subexpression is executed.
In your case:
i < j || ++j < k
The operators are effectively grouped as follows:
(i < j) || ((++j) < k)
Only the || operator dictates the order in which its operands are evaluated. The others do not. This means that i < j must be evaluated before (and if) ++j < k is evaluated, regardless of what the right-hand side of || contains.
As an example of order of evaluation, suppose you had this expression:
f() + g() * h()
The functions f, g, and h may be called in any order. Just because g() * h() has to be evaluated before the addition is evaluated doesn't mean that f won't be called first.

Related

C - Incrementation not updating variable value

I am working on a simple C program, but ran in to some confusion. Below is the code:
int main(void) {
int i, j, k;
i = 3;
j = 4;
k = 5;
printf("%d ", i < j || ++j < k);
printf("\n"); // LINE 1
printf("%d %d %d", i, j, k); // LINE 2
return 0;
}
In the above program, the variable j starts off being 4. Then in the printf statement of line 1 we increment the value of j by 1(++j = 5).
So theoretically, I would assume that when j is printed in printf(line 2) it prints as 5, since we did an incrementation in line 1 for j. However, every time I run the code, line 2 prints the original value of j which was 4, and NOT 5.
Is there something I am missing?
j is never incremented because ++j is never evaluated. The OR operator is satisfied when it first checks i < j.
This is an example of short-circuiting evaluation. When a boolean expression is A || B, if A is true, there is no need to evaluate B, and most languages adhere to that.
In this case, i < j is true, so the ++j < k is ignored.
This is a good example to learn "what is short-circuit evaluation". In the boolean expression (i < j || ++j < k) that you used above; || is the short-circuit OR.
So, to get the result as TRUE in the boolean expression one being true of one condition is enough. When considering i
In brief the difference between | and || is | consider the both conditions whether the first one is true. But || nevwr consider or process the second condition if the first condition is true and it jumps to the next line.
Looking at this expression:
i < j || ++j < k
The preincrement operator ++ has the highest precedence followed by the less-than operator < followed by the logical OR operator ||. So it parses like this:
(i < j) || ((++j) < k)
The logical OR operator || evaluates to true (specifically the value 1) if either the left side or the right side evaluates to true. Because of this, it also has the property that the right side will not be evaluated if the left side evaluates to true, since the result of the whole expression is already known at that point. This is commonly referred to as short-circuit evaluation.
This behavior is dictated by section 6.5.14p3 of the C standard regarding the logical OR operator:
Unlike the bitwise | operator, the || operator guarantees left-to-right evaluation; if the second operand is evaluated, there is a sequence point between the evaluations of the first and second operands. If the first operand compares unequal to 0, the second operand is not evaluated.
Going back to the expression, i < j is evaluated first. The value of i is 3 and the value of j is 4, so 3 < 4 evaluates to 1. Because this is the value of the left side of the || operator, the result of the || operator is 1 and the right side ++j < k is not evaluated, so j is never incremented.
This is called short-circuit evaluation. If i < j equates to true then ++j < k will not be evaluated.
This is a good example to learn "what is short-circuit evaluation". In the boolean expression (i < j || ++j < k) that you used above; || is the short-circuit OR.
So, to get the result as TRUE in the boolean expression one being true of one condition is enough. When considering i
In brief the difference between | and || is | consider the both conditions whether the first one is true. But || nevwr consider or process the second condition if the first condition is true and it jumps to the next line.

If ++ (pre/post) have higher precedence, why && is being evaluated first? [duplicate]

This question already has answers here:
Behaviour of && in C programming language
(5 answers)
Closed 9 years ago.
Here's my program:
int main(void)
{
int i, j, k, m;
i=-3, j=2, k=0;
m = k++ && ++i && ++j;
printf("%d, %d, %d, %d\n", i, j, k, m);
return 0;
}
The output of the program above is:
-3 2 1 0
But according to operator precedence table, ++ should have evaluated first I guess.
I also tried putting parenthesis around them, but still the output remains same.
I read somewhere that putting parenthesis around will make it evaluate first, no matter what.
Somebody, please make it clear, how it's evaluated.
Thanks in advance.
What's happening here is short-circuiting. k++ evaluates to 0, which is false. Thus the entire boolean expression k++ && ++i && ++j is false, so ++i and ++j are never executed.
You are confusing precedence with order of evaluation. Precedence defined how the operands are grouped. The higher precedence of ++ makes the expression equivalent to:
m = (k++) && (++i) && (++j);
But the evaluation order is irrelevant. The shortcut circuit of && guarantees
that its left-hand operand is evaluated first.
In general, most operator doesn't specify the order of evaluation, with four exceptions: logical AND &&, logical OR||, conditional operator ?: and comma operator ,.
As a concrete example of different order of evaluation:
Given int i = 0, the result of i + (i++) is unspecified, the compiler may evaluates i++ first, which modifies the value of i, the compiler may choose to evaluates i first. You should avoid expressions like these.
On the other hand, the result of i && (i++) is determined, as && ensures the left operand i is evaluated first, since it's zero, the right operand i++ is never evaluated.

Precedence of && over || [duplicate]

This question already has answers here:
Evaluation of the following expression
(3 answers)
Closed 3 years ago.
As I know logical operator && has higher precedence than ||. On running the code:
#include <stdio.h>
int main()
{
int i = 1, j =1, k = 1;
printf("%d\n",++i || ++j && ++k);
printf("%d %d %d",i,j,k);
return 0;
}
is giving the output:
1
2 1 1
which is possible only when ++i || ++j && ++k is evaluated like this:
(++i) || (++j && ++k)
But, according to operator precedence rule it should be evaluated as:
(++i || ++j) && (++k)
and hence output should be:
1
2 1 2
What is going wrong with this?
NOTE: As per my understanding I think an operator of higher precedence evaluated as follows(if it is left associative):
1. Evaluate its left expression
2. Then evaluate its right expression(if needed)
Am I wrong?
The || operator short-circuits - if its first operand evaluates to true (nonzero), it doesn't evaluate its second operand.
This is also true for &&, it doesn't use its second operand if the first one is false. This is an optimization that's possible because any boolean value OR true is true, and similarly, any boolean value AND false is always false.
OK, so you're confusing precedence with evaluation order. Nothing is contradictional here at all:
++i || ++j && ++k
is grouped as
(++i) || (++j && ++k)
since && has higher precedence. But then the LHS of the OR operation is true, so the whole RHS with its AND operation is discarded, it isn't evaluated.
To your note in the edit: yes, you're wrong: operator precedence is still not the same as order of evaluation. It's just grouping.
You say:
which is possible only when ++i || ++j && ++k is evaluated like this:
(++i) || (++j && ++k)
But, according to operator precedence rule it should be evaluated as:
(++i || ++j) && (++k)
The first grouping is correct because the precedence of && is higher than the precedence of ||. Then the expression as a whole evaluates the LHS of the ||, with the side-effect of incrementing i, which evaluates to true. That means that the RHS of the || (the && expression) is not evaluated at all because it is not needed to determine the truth of the overall expression.
So, the compiler is correct; you misunderstood precedence in some way.
Why is the first grouping correct? According to first grouping || has higher precedence than &&. What is going wrong with me?
You don't understand precedence, it seems, or you don't understand the interaction of precedence with order of evaluation. The first grouping gives higher precedence to &&.
If you have a + b * c, where * has a higher precedence than +, then it is evaluated as a + (b * c), is it not? Change + to || and * to && and the expressions are isomorphic and the interpretation is similar.
The big difference between the arithmetic expression and the logical expression is that the operands of the logical expression have to be evaluated left-to-right but the operands of the arithmetic expression do not; the compiler could evaluate b * c before evaluating a (but must evaluate b * c before doing the addition). By contrast, in the logical expression (a || b && c), the compiler must evaluate a before evaluating b && c, and when a turns out to be true, it must not evaluate either b or c, let alone b && c.
Firstly, as you said it yourself, && has higher precedence, which means that operand grouping should be
(++i) || (++j && ++k)
Why you are saying that "according to operator precedence" it should be (++i || ++j) && (++k) is not clear to me. That just contradicts what you said yourself.
Secondly, operator precedence has absolutely nothing to do with order of evaluation. Operator precedence dictates the grouping between operators and their operands (i.e. operator precedence says which operand belongs to which operator).
Meanwhile, order of evaluation is a completely different story. It either remains undefined or defined by completely different set of rules. In case of || and && operators the order of evaluation is indeed defined as left-to-right (with mandatory early completion whenever possible).
So, operator precedence rules tell you that the grouping should be
(++i) || ((++j) && (++k))
Now, order-of-evaluation rules tell you that first we evaluate ++i, then (if necessary) we evaluate ++j, then (if necessary) we evaluate ++k, then we evaluate && and finally we evaluate ||.
Since you are misunderstanding precedence, let's try to clear it up with a mathematical example. Multiplication and division have a higher precedence than addition and subtraction. Which means that this expression:
a + b * c - d / e
Can be written like this:
a + (b * c) - (d / e)
Since you correctly stated that && has higher precedence than ||, this expression:
i || j && k
can be written like this:
i || (j && k)
You can think of it as "the operation with the highest precedence gets parenthesized first", if that helps.
(But precedence is different from evaluation - if i is true, then (j && k) will never be evaluated.)

Evaluation of the following expression

The following code snippet:
int i=-3,j=2,k=0,m;
m=++i && ++j || ++k;
can be evaluated using two concepts,I believe:
1.Since ++ operator has greater precedence than the logical operators,so first all increment operators will be evaluted,then && having higher precedence than || will be computed.In this process,k will be incremented.
2.First && operator will be evaluated.For this ++ i and ++j will be computed.Since the result of the && operator is 1,no need to evaluate the ++k.So k will not be incremented.
When I try it on a system, the result proves reasoning 2 to be correct and 1 to be wrong. Why is it so?
Oli is right... You're confusing precedence with evaluation order.
Precedence means that the expression is interpreted as:
m = ((((++i) && (++j)) || (++k));
As opposed to, say:
m = (++(i && ++(j || (++k)))
Precedence doesn't change the fact that the LHS of the || operator will always be evaluated before the RHS.
In attempting to be efficient, evaluation of an OR statement (executed from left to right) stops when the LHS is true. There is no need to start evaluating the RHS - there is no concept of "precedence" except within the same group of an expression (when it matters to the value of the expression whether you first do A or B. Example: 5 + 3 * 2 should evaluate to 11. But in evaluating ( 5 + 6 > 3 * 2) it doesn't matter whether you do the addition before the multiplication - it doesn't change the result of the comparison. And in practice this gets evaluated left-to-right. Thus you get the result you observed.
See also this earlier answer
The && and || operators force left-to-right evaluation. So i++ is evaluated first. If the result of the expression is not 0, then the expression j++ is evaluated. If the result of i++ && j++ is not 1, then k++ is evaluated.
The && and || operators both introduce sequence points, so the side effects of the ++ operators are applied before the next expression is evaluated. Note that this is not true in general; in most circumstances, the order in which expressions are evaluated and the order in which side effects are applied is unspecified.

How come j is not incremented in this example?

C newbie here, and I'm wondering, how come j is not incremented in the example below?
I searched everywhere for an explanation
int i, j, k;
i = 3; j=4; k=5;
_Bool checkbit;
checkbit = i < j || ++j < k;
printf("%d\n", checkbit );
printf("%d %d %d\n", i, j , k);
The output is
1
3 4 5
instead of
1
3 5 5
Thanks!
Because it doesn't need to be evaluated.
checkbit = i < j || ++j < k;
i < j will yield true, so no matter what the second part of the expression yields, the value of checkbit will be true. Thus, it doesn't even bother evaluating it.
Just for kicks:
checkbit = i > j && ++j < k;
In this case, the second expression will not be evaluated because false && (expr) is false.
Double-Or is "Shortcutting" - it won't evaluate the rest of the expression if the first part is true.
Use a single-or to increment it whatever happens.
This can be useful sometimes. It speeds up execution, because if the first part is true, you know the result of the or must be true!
Note that this is the same (in reverse) for &&: If the first part of && is false, then the second part is ignored, as you know the result will be false.
And it's perhaps worth mentioning that this behavior, short-circuit evaluation, is in the C standard:
6.5.14 Logical OR operator
Syntax
1 logical-OR-expression:
logical-AND-expression
logical-OR-expression || logical-AND-expression
Constraints
2 Each of the operands shall have scalar type.
Semantics
3 The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it
yields 0. The result has type int.
4 Unlike the bitwise | 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
unequal to 0, the second operand is not evaluated.
(emphasis mine)
When using || operator, and the first condition evaluates to true, it ignores the rest unlike the && operator
checkbit = i < j || ++j < k; //since i < j is true, it skips over ++j < k

Resources