C: Is there any wrong understanding about short-circuit evaluation? [duplicate] - c

This question already has answers here:
Short circuit evaluation of a statement with ++ operator in C
(2 answers)
Closed 6 months ago.
The community reviewed whether to reopen this question 6 months ago and left it closed:
Original close reason(s) were not resolved
Hi I have little confused about logical operator.
According to KNK C chapter 5 exercise 3-4.
int i=1;
int j=1;
int k=1;
printf("%d\n",++i || ++j && ++k);
printf("%d %d %d",i,j,k);
I thought the result is 1\n 2 1 2 due to the short -circuit evaluation
like ((++i || ++j) && ++k ).
But the answer is 1\n 2 1 1.
Why does variable k increase?

From C Operator Precedence:
Precedence
Operator
Description
Associativity
11
&&
Logical AND
Left-to-right
12
||
Logical OR
Left-to-right
Since && has precedence 11 and || has 12, the expression ++i || ++j && ++k is equal to this:
++i || (++j && ++k)
Left-to-right associativity makes it evaluate ++i first, concludes that it's true and short-circuits so (++j && ++k) will not be evaluated.
The result is therefore
1
2 1 1

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.

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.

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.

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.

Please explain an apparent conflict between precedence of && and || and the actual result of an expression [duplicate]

This question already has answers here:
Precedence of && over || [duplicate]
(4 answers)
Closed 8 years ago.
I don't understand the output of the following program:
#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;
}
The output is -2 2 0 1 instead of -2 3 1 1, implying that ++i was evaluated (and caused the || operator to short-circuit its right hand side) before the expression ++j && ++k which appears to contradict the fact that the && operator has higher precedence than ||.
Would someone explain why?
The output should be something like:
Error, line 2: 'm': undefined variable.
Edit: with that fixed, only the ++i should be evaluated. Precedence does not determine (or even affect) order of evaluation. Precedence means the expression is equivalent to ++i || (++j && ++k). Order of evaluation for || or && is always that the left operand is evaluated, then there's a sequence point. After the sequence point, the right operand is evaluated if and only if necessary to determine the final result (i.e., the right operand of || is evaluated if the left operand evaluated to zero; the right operand of && is evaluated if the left operand evaluated to non-zero).
In this expression, ++i is evaluated, then because it's the left operand of || and evaluated non-zero, none of the rest of the expression is evaluated.
-2 2 0 1
Lazy.
#include <stdio.h>
int main()
{
int i=-3,j=2,k=0;
int m=++i||++j&&++k;
printf("%d %d %d %d",i,j,k,m);
}
Compile, run and see for youself.
gcc tmp.c -o tmp
The expression:
++i || ++j && ++k
Is equivalent to:
(++i) || ((++j) && (++k))
Explaining:
++i is evaluated -- (-2) || ((++j) && (++k));
The || operator is evaluated -- (1);
Since 1 || anything evalutes true, the right operand is not evaluated. Thus, the && precedence doesn't matter here. This short circuiting is guaranteed in both C and C++ by the relevant standards (see Is short-circuiting logical operators mandated? And evaluation order?).
Now, try using a sub-expression, like this:
(++i || ++j) && ++k
Which is equivalent to:
((++i) || (++j)) && (++k)
Explaining:
++i is evaluated -- ((-2) || (++j)) && (++k);
|| is evaluated -- (1) && (++k)
++k is evaluated -- (1) && (1);
Evaluates true;
By way of explanation:
#include <stdio.h>
int main()
{
if (-1)
printf ("-1!\n");
else
printf ("Not -1.\n");
return 0;
}
Negative numbers are not false in C. Always compare boolean values to 0 (or FALSE) or you can get bitten by if (worked == TRUE) giving false negatives.

Resources