Determining the print of C - c

I'm reviewing material on C. I'm not sure why the answer is 12 and 32. In the first printf(), I thought that %d = 2 (i), %d = 2 (j), \n = new line. Can anyone explain this?
#include <stdio.h>
int main(void) {
int i,j;
i=2 && (j=2);
printf("%d%d\n",i,j);
(i=3) || (j=3);
printf("%d%d\n",i,j);
}

For the first expression, i=2 && (j=2); is implicitly evaluated as i = (2 && (j = 2)); because the assignment operator = has lower precedence compared to the logical operators. In the first condition, 2 has the truth value of true, and logical AND && causes all conditions to be evaluated, meaning j = 2 is also evaluated, assigning 2 to j and returning 2 which evaluates to true. So now the actual expression to be evaluated is i = 2 && 2; which is true, or in C's terms, 1. So, i is assigned 1, and the first output is 12.
For the second expression (i=3) || (j=3);, the logical OR || is used, and short circuiting ensures that if the first condition evaluates to true, the overall expression is true and so the second condition is not evaluated. So after i = 3 is evaluated, i is assigned 3 and the entire expression is true, so j = 3 is not evaluated. And so the second output is 32.

Based on precedences, the first expression is evaluated as
i = (2 && (j=2));
So i=1 (true) and j=2. That is why the first output is 12.
The second expression is a logical OR of two assignments.
(i=3) || (j=3);
But since the first evaluation from left is "true" (i=3) the second evaluation is not done. That is why value of j remains 2 and the second output is 32 (not 33).

The reason 12 is printed instead of 22 is because i is assigned the value of 2 && (j=2). First j gets assigned to 2. Then (j=2) returns 2. After that 2 && 2 is evaluated to true, and it returns true. This is because && checks if both sides are true, and 2 is interpreted as true. Since both sides are true, it returns true which is 1.
The || does not evaluate right hand side if left is evaluated to true. The reason is that it is not necessary. It should evaluate to true if at least one of the operators evaluates to true, and i=3 evaluates to 3 which is interpreted as true. That's why 32 is printed instead of 33.
The feature that it does not evaluate right operand if left evaluates to true can be used to do this:
foo() || printf("foo() returned false\n");
And similar for &&, but this operator does not evaluate right operand if left evaluates to false.
foo() && printf("foo() returned true\n");
Note that I'm not suggesting that these tricks should be used. I'm just using them as an example of how || and && may skip evaluating the right operand depending on the value on the left.

Related

Post increment inside expression of if statement

In the code below, I was expecting answer 'Yes'. But the answer is no. That means i is getting incremented after && operation. I was expecting that i gets incremented once entire expression inside if() is evaluated. So what are the rules associated with post increment?
int main()
{
int i = 1;
if (i++ && (i == 1))
printf("Yes\n");
else
printf("No\n");
}
The logical AND operator && has a sequence point between the evaluation of the left operand and the right operand. That means the left operand is evaluated first, along with any side effect (in this case the increment).
In this expression, i starts with a value of 1. So the expression i++ has a value of 1, and the value of i is incremented.
As the left side of the && operator this value evaluates to true, so the right side is then evaluated. If the value was 0 i.e. false the right side would not be evaluated.
At this point the value of i is 2, so i == 1 evaluates to false, making the result of the && operator false. This results in the else clause being executed.
it compiles from left to right, up to down, so it's logical that you're having a 'No', your if statement contains i++ which will cause i to be equal to 2 and then returns true, then it contains i==1 which will return false since i is no longer equal to 1, so your if statement is returning false which will make it execute what's on the else, means 'No'.
A simple explanation about logical operators:
&&: evaluated from left to right, and all the evaluated conditions must return 'true' so it can be true.
||: evaluated from left to right as well, except that it ends the evaluation with true, once finding one true condition.

What is the order of evaluation of the statements in this code?

I came across this question.
#include <stdio.h>
int main()
{
int k=8;
int x=0==1||k++;
printf("%d %d",x,k);
return 0;
}
The output is 1 9.
As this answer suggests that
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.
I am unable to understand how the statement int x=0==1||k++ is evaluated,due to which the value of x and k becomes 1,9 respectively.
Can someone explain how such statements are evaluated by the compiler in c ?
"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."
yes it's true ...
to make it clear first make sure that you are aware of these basics
1) (1 || any_var) is 1
2) Operator precedence is as follows
++
then
==
then
||
NOW coming to your doubt of || vs |
note that | (single pipe) operator ..,will execute both LHS and RHS , no matter what)
whereas
|| (double pipe) evaluates LHS of || first and if it is 1 it need not evaluate RHS (for speed)
RHS of || operator will not be evaluted if LHS comes out to be true.
but here 0==1 is false i.e 0==1 returns 0
hence RHS will be evalauted
so the statement
k++ is executed
but 8 is used (as property of post increment operator says--> first use then increment)
so 0||8 is definitely true (1) so x evaluates to 1
and then k is incremented after sequence point ie k is made equal to 9
hence output x=1 and k=9
I hope it clears your doubt :)
The Operator || (OR) evaluates to true in the cases:
ex: A || B
A is true,
B is true,
Both are true
Because this operation uses Short-Circuit Evaluation if A is evaluated to true, it means that the statement is true already and it won't evaluate B.
In your case 0==1 (0 equals 1) is clearly false, so it will evaluate k++. k++ is a tricky one (in my opinion). In the world of C true/false evaluation is based on being 0 or not (except for the times false means less than 0...) but in true/false evaluation 0 is false, everything else is true.
K++ means evaluate K then increment, so, if K is 0 it will be false and become 1, if it is anything else, it will be true and then increment.
In your case k == 8 so the result of k++ is TRUE and k will become 9. K being true means x evaluation resulted in TRUE (it was FALSE OR TRUE).
So the output is 1(True) 9(8++)
x is 1 because the expression: 0==1||k++ turns out to be true (which is 1 in C land). Why you ask? There are two sequence points here: 0 == 1 and k++. Since the first sequence point evaluates to false (0 in C land), the second sequence point is evaluated (because the short circuit operator is ||). The second sequence returns true (or 1). So, you the entire expression breaks down to: 0 || 1. Hence x is 1.
k is 9 because of k++;
HTH.

Logical operator with Arithmetic operator in C

I came across a question and I wanted to verify whether my assumptions were correct.
Given the following codes:
1. int i = -2, j = 1, ans;
2. ans = i++ || ++j;
3. printf("%d %d %d", i,j, ans);
The output is: -1 1 1
In C language, it seems that only 0 will be treated as false, any other values will be treated as true when used with a logical operator. So I am not doubtful why ans derives to 1 (true || true gives us true(1) )
What I wanted to ask here is: Why is the value of j still 1 and not 2 despite ++j?
Can safely assume that any arithmetic operations after the logical operators || && will only be effective at the line it is used(in this case, line 2), and after which the variable still retain its original value?
|| operator wont do any operation on second operand when first operand is nonzero.
Because, any one of the operand is non-zero then, output will be true in || operator operation. In your code 1st operand is non-zero. Thats why operation on second operand is not performed.
As in Second Line of your Code i.e
ans = i++ || ++j;
first it will check i++ as it is not zero that means it is true.
And in OR Condition if first condition is true it will not check second condition i.e ++j.
Because if first condition is true is doesn't matter, Second condition is TRUE or FALSE it will return a true value. So if First Condition is true it will not check the other condition.
Logical operators short circuit. That is, in the following:
ans = i++ || ++j;
++j will never be evaluated if i++ evaluates to true (non-zero).

Side effect vs value calculation in GCC ternary conditional operator?

I have the following code which produces unexpected results to me:
#include < stdio.h >
int a = 0, value;
int main(void)
{
// Testing the evaluation order of multiple
// conditional operators:
value = (a == 3) ? 3 : (a = 3) ? 5 : 0;
printf("%d\n", value);
return 0;
}
I was expecting for this code to print 3, seeing that the conditional operator evaluates
from right to left and that there is a sequence point at the ? of the first-to-be executed
operation, whereas it actually prints 5.
Is it wrong to assume that side effects of an expression residing between two sequence
points also get calculated when the values of the expressions are?
If i add printf("%d\n" a); i get 3 printed though, so the side effect gets done.
Or is it just that control dosent really pass to the subexpression the value of which
is being calculated "first" officially?
I would rather bet on the latter because changing the value of 'a' to 3 and the rvalue
in the assignment of the second conditional to 4 resulted in short-circuit evaluation
of the first conditional expression, meaning that i got 3 printed for both 'a' and 'value'.
I got the above result on Lubuntu 14.04 with GCC 4.8.2 using the -std=c99 flag.
Thank you for anyone clearing me up on this matter!
The conditional operator does not "evaluate right to left". The standard (C11 6.5.15/4) says:
The first operand is evaluated; there is a sequence point between its
evaluation and the evaluation of the second or third operand
(whichever is evaluated). The second operand is evaluated only if the
first compares unequal to 0; the third operand is evaluated only if the
first compares equal to 0; the result is the value of the second or
third operand (whichever is evaluated)
So the expression (a == 3) ? 3 : (a = 3) ? 5 : 0; evaluates in these steps:
(a == 3) result is 0
(a = 3) result is 3, unequal to 0
5
So 5 is what is assigned to value.
You might be confusing the concept of how the conditional operator is evaluated with how the conditional operator associates (or groups). The syntax of C specifies that the expression:
(a == 3) ? 3 : (a = 3) ? 5 : 0;
associates or groups sub expressions like so:
((a == 3) ? 3 : ((a = 3) ? 5 : 0));
which is often described as 'associates right'. However, this grouping/associativity doesn't affect the fact that the expression is still evaluated left-to-right and that the second conditional expression only evaluates after the first operand in the 'outer' conditional expression is evaluated.
Let's trace through this one part at a time. You have this expression:
value = (a == 3) ? 3 : (a = 3) ? 5 : 0;
Since a starts off at 0, we skip the 3 branch of the first ?: and look at the second branch, which is
(a = 3) ? 5 : 0
The condition here is a = 3, which sets a to 3 and then evaluates to the new value of a, which is 3. Since 3 is nonzero, we take the first branch of the ?:, so the expression evaluates to 5. The net effect is that a is set to 3 and value is set to 5.
The language spec guarantees that the evaluation order is indeed what you think it should be - the "if" and "else" branches of the ?: operator are guaranteed not to execute unless the condition works out as it does, so there are sequence points here. I think you just misunderstood the effect of the a = 3 operation.
Hope this helps!
The conditional operator evaluates left-to-right (evaluating the condition before either of the branches). You may be confusing this with its right-associativity (in which it appears to bind right-to-left).
Your conditional expression essentially results in the following logic:
if(a == 3) {
value = 3;
} else {
if(a = 3) {
value = 5;
} else {
value = 0;
}
}
Note that the conditional doesn't execute a branch until after the condition is evaluated.

Require explanation for the output

Code:
#include<stdio.h>
int main()
{
int j = 7, i = 4;
j = j || ++i && printf("you can");
printf("%d %d",i,j);
return 0;
}
Output:
4 1
[Code Link][1]
The precedence of prefix operator is higher than logical operators.
2.Logical && has higher precedence than logical ||.
In Logical AND(&&) if first operand evaluates to false than second will not be evaluated and In Logical OR(||) if first operand evaluates to true, then second will not be evaluated.
The complete expression is evaluating to true, therefore j is 1 .
Doubts:
Why the first rule is not followed here? Shouldn't it be correct?
j=(j||((++i) &&printf("you can")));
Therefore value of i becomes 5, in the printf statement.
Why are the general precedence rules are violated here? Associativity comes into action when precedence of two operators is same. Shouldn't the compiler first see whether to evaluate || or &&?
If || is evaluated first, which shouldn't be as per my knowledge, then result is correct. However, if it is not evaluated first, then you can51 should be printed.
In this expression:
j = j || ++i && printf("you can");
There's a sequence point after the || and it is evaluated from left to right. Since j is non-zero, the rest of the expression is not evaluated. Hence, j || (....) becomes true which is 1. Since is ++i is not evaluated i remains 4. Hence, the output is 4, 1.
From the C standard:
Annex C
— The end of the first operand of the following operators: logical AND
&& (6.5.13); logical OR || (6.5.14); conditional ? (6.5.15); comma ,
(6.5.17).
If you j was zero then ++i && printf("you can") would have been evaluated and i would become 5 and you can will also be printed. You are correct about the precedence of ++ being greater than ||, but since there's a sequence point, j|| is evalauted first.
j || ++i && printf("you can") evaluates to true, which is represented by 1. Because it is an OR, and because j is non-zero, only the left hand of the OR is evaluated, so the ++i and the printf aren't evaluated. Thus j is 1 and i stays at 4.
Of course, real code should never every do anything like that. You should always write code in ways that the order of operations is obvious, and you should almost never have code with side effects in OR statements.
What you have here:
j = j || ++i && printf("you can");
Is a logic expression (there's no math happening). Let's break it down:
++i // as a mathematical expression this is i=i+1 (5 in your case)
printf("you can"); // printf returns the number of chars written, (7)
So you'd expect this to be:
j = 7 || 5 && 7;
The output of the above expression is simply 1. So even if this executed you should see j=1. So why don't you see the printf() output?
The reason to that is that whole expression didn't run. It doesn't have to. Consider:
result = TRUE || (anything else);
Anything that's "true" or'd with anything else will always return true. The compiler knows this and once it sees 7 || it equates that to true || and says "I know enough, set j to true and move on".
This is why the expression doesn't increment i and why it doesn't print "you can".
Now if you were to flip the expression:
j = ++i && printf("you can") || j;
The logic stays the same but the compiler doesn't see the || until it's evaluated everything else, so i will be incremented and the printf will be displayed.
I ran this program two ways:
j = j || ++i && printf("you can");
then, like this:
j = j || (++i && printf("you can"));
The output for both was 4 1. Before I ran them, I expected to get the exact same result from both due to the left to right associativity of logical or. The entire expression is gonna be evaluated from left to right regardless. The role of the parentheses is to ensure that an expression is evaluated as one expression, and doesn't necessarily mean that it will be the first expression to be evaluated. If you want more evidence of this, try something simple:
j = 1 || (++i);
Even though (++i) is in parenthesis, it is never evaluated. Again, because of left to right associativity.

Resources