Precendence vs short-circuiting in C [closed] - c

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
int i=-3, j=2, k=0, m;
m = ++i || ++j && ++k;
printf("%d, %d, %d, %d\n", i, j, k, m);
Since ++ has more precedence than || and && in C, they are evaluated first and therefore the expression becomes m = -2 || 3 && 1. Now you can apply short circuiting but that produces incorrect answer. Why is that?

Precedence ≠ order of evaluation.
The short-circuiting behavior of || and && means that their left-hand sides are evaluated first, and
If the LHS of || evaluates to true (nonzero), the RHS is not evaluated (because the expression will be true no matter what the RHS is)
If the LHS of && evaluates to false (or zero), the RHS is not evaluated (because the expression will be false no matter what the RHS is)
In your example, ++i gets evaluated, and is equal to -2, which is nonzero, so the right-hand side of the || (that is, ++j && ++k) never gets evaluated: j and k are never incremented.

The ++s don't execute before the expression. Only ++i executes, which indicates that the result of the expression will be 1, therefore the rest of the expression is not evaluated (short circuit).
Your code is equivalent to:
if (++i)
m = 1;
else
if (!++j)
m = 0;
else if (!++i)
m = 0;
else
m = 1;
This means that once ++i is evaluated to true, the else part is never executed.

Related

how the precedence and associativity works in the following example? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
int i=3,j=1,k=0,m;
m=++i || ++j && ++k;
printf("%d%d%d%d",i,j,k,m);
//output is 4 1 0 1enter code here
//can anyone explain why k=0 and j=1 only
m = ++i || ++j && ++k; is grouped as m = ++i || (++j && ++k); since, && has higher precedence. But, they are evaluated from left to right.
Since, ++i = 4, which a non-zero number, the right hand expression is not evaluated. I mean (++j && ++k) is not evaluated since, left hand expression result is non-zero.
For A||B, if A = 1, then results is always 1, irrespective of the value of B.
Since, the right hand expression is not evaluated, the values of j and k remain same.
This feature is called "Short Circuit Evaluation".
Precedence and associativity only affect how operators are grouped with operands - they do not affect the order in which expressions are evaluated. Both || and && force left-to-right evaluation. Also, remember that the && and || operators short-circuit as follows:
In the expression a || b, b will only be evaluated if a evaluates to zero
In the expression a && b, b will only be evaluated if a evaluates to non-zero
The expression
++i || ++j && ++k
is parsed as
(++i) || ((++j) && (++k))
and is evaluated as follows:
++i is fully evaluated and all side effects applied;
The result of ++i is 4, which is non-zero;
The || does not evaluate the right operand if the left operand is non-zero, so ++j && ++k is not evaluated at all;
When everything is said and done, only i is updated, j and k are not.

Increment and logical operators precedence [duplicate]

This question already has answers here:
Short circuit behavior of logical expressions in C in this example
(1 answer)
Operator Precedence vs Order of Evaluation
(6 answers)
Closed 7 years ago.
In the program shown below, prefix should be evaluated first because it has higher precedence, But answer is -2, 2, 0, 1 and it is explained in book "as LHS of || is true RHS is not evaluated."
Why is it so? All the increments should performed first and then logical should be checked because of precedence.
#include<stdio.h>
int main()
{
int i=-3, j=2, k=0, m;
m = ++i || ++j && ++k;
printf("%d, %d, %d, %d\n", i, j, k, m);
return 0;
}
Don't get confused with Precedence and Order of evaluation.
The order of evaluation of logical OR || is left to right.
So if left = true then left || right will never execute right. In your code exactly same happened.
As you know, any non zero value treated as true in C, hence, ++i or -2 is true. So,
m = ++i || ++j && ++k;
m = true || bla bla bla; //right not even checked!
m = true
m = 1
And you get the output as expected.
The logical && and || operators fully evaluate the LHS before doing any evaluation of the RHS.
In the code shown, since ++i is -2, the LHS of the || evaluates to true (1) and the RHS is not evaluated. Therefore, neither j nor k is incremented. The printed result follows: m was assigned 1, i became -2, and j stayed as 2 and k stayed as 0.
The only remaining issue is that && binds tighter than ||, so:
a || b && c
is equivalent to:
a || (b && c)
so if a evaluates to true (non-zero), then neither b nor c is evaluated.
Operator precedence is a completely different thing. Order of evaluation is determined by side effects and sequence points.
see this manual on order of evaluation.

Understanding operators in C [duplicate]

This question already has answers here:
OR and AND operation in C
(2 answers)
Closed 7 years ago.
I am struck on a basic problem with operators. Here is the problem
int i=3, j=2, k=1, m;
m = ++i || ++j && ++k;
printf("%d %d %d %d", i, j, k, m);
As i worked on this and evaluated the ans as
4 3 2 1
But C is not happy with my ans and evaluates the above as
4 2 1 1
But i dont understand how. Why ++j is doesn't updates the value of j. And also ++k doesn't updates the value of k.
Anybody here please explain this how it worked.
m = ++i || ++j && ++k;
The && operator has higher precedence than ||, so this is equivalent to:
m = ++i || (++j && ++k);
Both && and || are short-circuit operators; if the left operand determines the result, the right operand is not evaluated. Since ++i (which yields 4) is "truthy", the right operand (++j && ++k) is not evaluated, and j and k are not incremented. So i becomes 4, and j and k retain their initial values of 2 and 1, respectively.
The result of the || operator is either 0 (for false) or 1 (for true); since the condition is true, the value 1 is assigned to m.
Result:
4 2 1 1
In C, || is a short-circuit operator. This means when evaluating the expression a || b, it will only evaluate b if a is false. If a is true, then the expression will always be true regardless of b.
Since ++i gives a truthy value, ++j && ++k will not be evaluated.

Post-increment and pre-increment operator in C [duplicate]

This question already has answers here:
Is short-circuiting logical operators mandated? And evaluation order?
(7 answers)
Closed 5 years ago.
Why is k not getting incremented whereas,i and j are getting incremented in the same expression.And i also want to know what is the output of the program.I am getting the output as
-2 3 1 0
#include <stdio.h>
void main()
{
int i=-3, j=2, m, k=0;
m=++i && ++j || ++k;
printf("%d %d %d %d", i, j, m, k);
}
The logical or, || short-circuits, and after
++i && ++j
the value of the entire expression is determined, so the right operand of the || isn't evaluated.
m=++i && ++j || ++k;
is parenthesized m = (++i && ++j) || ++k; since the && has higher precedence than the ||.
The short-circuiting of the logical operators means that the right operand is only evaluated when the evaluation of the left has not yet determined the final result, for || that means the right operand is only evaluated if the left evaluated to 0, and for &&, the right operand is only evaluated if the left evaluated to a nonzero value.
So first ++i && ++j is evaluated, and for that, first ++i is evaluated. i had the value -3 before, so ++i evaluates to -2, which is not 0, hence the ++j is evaluated too. j had the value 2 before, so ++j evaluates to 3, which is again nonzero, and thus ++i && ++j evaluates to 1 (true). Since the left operand of the || is not zero, its result is already determined (to be 1), and the right operand isn't evaluated, thus k remains unchanged and m is set to 1.
If the item on the left of an || condition evaluates to true, there is no point evaluating the right hand side since the OR condition is already satisfied. That is why the ++k is not being evaluated
These operators are known to be short-circuited operators. So, if the expression ++i && ++j is true, it does not evaluate k (we know the value of the expression regardless to the value of k).
It has to do with order precedence. Anytime a logical OR is executed, it will stop if the first operand is true, which in this case is j.
The logical operator || works like this: if first condition is true then the second one is not evaluated.
So first (++i && ++j) checks. It returns true, so after it || is not evaluated. Thus, the value of k is not increased.
#include<stdio.h>
int add(int);
void main()
{
int i=3,k,l;
clrscr();
k= add(++i);
l=add(i++);
printf("i=%d k= %d l=%d",i,k,l);
getch();
}
int add(int ii)
{
++ii;
return(ii);
}
/*th eoutput is
5
5
5 can anyone expalin how? */
#include"stdio.h"
#include"conio.h"
main()
{
int rmv=10,vivek=10;
clrscr();
rmv++;//this post incremant means incremant next step 10+1
//rmv+1 and rmv++ both are same
printf("1.rmv++=%d\n",rmv);//value is 10
printf("2.rmv++=%d\n",rmv++);//the value is increment 11
++vivek;//this pre increment means first increment the value so,1+10=11
printf("1.\t++vivek=%d\n",vivek);////++vivek and 1+vivek both are same
printf("2.\t ++vivek=%d",++vivek");
getch();
}

How the given C code be interpretated by different Compiler [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
I have a code below and wanted to know what could be output.What i would like to see how different compiler would interpret this particular piece of code.
int main()
{
int i = -1, j = 2, k = 0, m;
m = ++i || ++j && ++k;
printf("\n %d %d %d %d \n", i, j, k, m);
return 0;
}
Now the question is while handling this code would compiler go by the rule which says
This expresion can be seen as
m = ++i || (++j && ++k);
as && has higher precedence over || and the result would be 0 2 0 1
or
This expresion can be seen as
m = ++i || (++j && ++k);
but compiler still will try to short circuit. so it evaluates ++i, since it's 1,(++j&&++k) >are not evaluated.so ans is 0 3 1 1
The expression ++i || ++j && ++k will group like so due to precedence:
++i || (++j && ++k)
One of the few rules C has about evaluation order of expressions is that the left-hand side of the || and the `&& operators must execute before the right-hand side (for short circuiting). This is a non-optional language requirement.
That means that ++i has to be evaluated first. It will return 0 (it does not evaluate to 1 as you mistakenly mention in the question). Since that's not enough to short circuit the || operation, the right side will need to be evaluated. A similar process will occur for evaluation the && operator (and both sides of the && operation will need to be evaluated).
The resulting output will be:
0 3 1 1
regardless of the compiler. There is no undefined, unspecified, or implementation defined behavior evaluating that expression.
The expression ++i || ++j && ++k will group like so due to precedence:
++i || (++j && ++k)
One of the few rules C has about evaluation order of expressions is that the left-hand side of the || and the `&& operators must execute before the right-hand side (for short circuiting). This is a non-optional language requirement.
That means that ++i has to be evaluated first. It will return 0. Since that's not enough to short circuit the || operation, the right side will need to be evaluated. A similar process will occur for evaluation the && operator (and both sides of the && operation will need to be evaluated).
The resulting output will be:
0 3 1 1
regardless of the compiler. There is no undefined, unspecified, or implementation defined behavior evaluating that expression.
One way to get the output you mention in your question is to use the following expression instead:
m = --i || ++j && ++k;
In this case, --i evaluates to -2 and the short circuiting rule requires that the right side of the || operator not be evaluated. So j and k are left alone.

Resources