Little detail about using operator "or" - c

Consider this code:
int a = 5;
if (a == 5 || a == 10)
doSomething();
In this case a is 5 so the first condition is true. Will the program check if the second condition is true or it will start executing doSomething() immediately after it makes sure that a is really 5?

It will start executing immediately. This is known as short-circuit evaluation.
http://en.wikipedia.org/wiki/Short-circuit_evaluation

The second condition won't be checked. C short-circuits logical evaluations, so as soon as the truth or falsehood of the condition can be determined it stops.
Note that given the code as posted, the compiler might not even generate code to perform the first comparison as it can determine at compile time that the condition is satisfied and no intervening code could alter the value of a.
Share and enjoy.

int a = 5;
if (a == 5 || a == 10)
doSomething();
in this example the left operand operand of || is evaluated to 1 so the right operand will not evaluated.
The compiler is required to not evaluate the right operand of || operator when the left operand is evaluated to 1.

When it comes to the logical operations, the compiler will stop evaluating the expression as soon as its finds the truth or falsehood of the expression.
The truth-table for logical or (||) operation is as follows:
A B A||B A&&B
0 0 0 0
0 1 1 0
1 0 1 0
1 1 1 1
So for an expression like a == 5 || a == 10, when a is equal to 5, the expression will be evaluated to true when the compiler sees a == 5 part. So irrespective of whether the rest of the expression is evaluated to true or false, due to the logical or (||) operator (refer the above truth-table), this expression will be evaluated to true. So the compiler will discard executing the rest of the expression.

Any decent compiler will not even check the first condition since at compile time it knows at once that it should invoke your method. (but of course all comments about short circuit hold true - but not here ;-)

Related

AND and OR operator c

Hey i am working on a code and i stuck inside this if condition which is
(Not a actual Code simplified for better understanding)
if(18&2==2)
do something;
this if condition not executing but if i write like this
if(18|2==18)
do something;
it executed normal
also when I,
printf("%d",18&2);
it gives 2 now i am so confused why the above if statement not executing,
is it because of precedence ,please explain thanks.
Yours is a precedence "error". The bit-wise operators have lower precedence than equality. Making 18 & 2 == 2 into 18 & (2 == 2), which is 18 & 1. That last one obviously evaluates to 0, since 18 is divisible by 2.
In such cases, when you get "weird results". Start by adding parenthesis to make sure every operator operates on the operand you expect it too.
The precedence of == is higher than &.
The expression:
if(18&2==2)
evaluated as follow:
2==2 result in logical true (1).
18&1 result in logical false (0);
Hence the if condition (18&2==2) evaluated as false.

Determining the print of 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.

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.

Can't understand this if statement

I've a C university exam coming up next week and i was looking at old exam papers a one of the questions gives this fragmented bit of code.
int a=2, b=-1, c=0;
if (a-2||b&&c||a){
printf("True\n");
} else {
printf("False\n");
}
We have to determine what the output of this code will be but the if statement makes no sense to me any if statement I've come across has been very specific like saying
if( x == 0)
I don't know what this is looking for my only assumption is that its going to be always true. Am I right or is there more to it then that?
This assignment has two goals:
to show what booleans are in C: Essentially they evaluate to ints with false mapping to 0 and true mapping to 1. In turn, any numeric or pointer value can be used in an integer context, with the respective zero value (0, 0.0, NULL (pointer), 0.0f, 0L etc.) evaluating as false and all others as true.
to show the precedence of operators
&& has a higher precedence than ||, so this statement is equivalent to
a-2 || (b&&c) || a
which will evaluate to true if any of the values is true.
As a==2, a-2 is 0. c is 0, so b && c is 0 as well.
So we have 0 || 0 || a, which is true as a is 2.
Most languages interprets non-zero integers as true and zero as false, so here you would have to calculate each one of the terms. Without any parenthesis, I would suggest that the && statement is taken in account first. So we have:
if (2-2 // gives zero
|| // OR
-1 && 0 // -1 AND 0 gives false
|| // OR
a) // Which is 2, which is true
So you're right, this statement is always true. This exercice was about showing predecence orders, and the fact that everything is numerical, even in boolean logic.
This is really important for you to understand.
If the predecence was the other way around (|| > &&), you must understand that it would have been false instead. I think this example's whole point is here.
(a-2 || b) && (c || a)
false && true
--> false
You need to understand that truth and falsity in C is always numerical.
https://www.le.ac.uk/users/rjm1/cotter/page_37.htm
Namely, anything that evaluates to numerical zero is false, and anything that evaluates to numerical non-zero is true.
In c language integers 0 is treated as false and any non-zero integer value is true but it should be noted that it is language specific and the sme statement will show compilation error in java as java is more strict and integers are not converted to booleans.
Talking about the above assignment problem the expression inside if statement will evaluate to true as
(a-2||b&&c||a) is same as
(2-2||-1&&0||2) which is same as
(0||0||2) which is evaluated as
(false||false||true) and hence the entire expression evaluates to
true.
hope it helps.
int a=2, b=-1, c=0;
int first=a-2; //0 -> false
bool second= b&& c; // nonZero&&zero -> true&&false -> false
int third = 2; // nonZero -> true
// false|| false|| true -> true
if (first || second || third ){
printf("True\n");
} else {
printf("False\n");
}
you need to understand two things before solving this problem that is
operator precedence and
associativity of operators
operator precedence tells c compiler that which operation to perform first.
and if two operators have same precedence than associativity tells evaluate left to right or right to left in you expression
int a=2, b=-1, c=0;
if (a-2||b&&c||a){
you can think it as
if((a-2)||(b&&c)||a){}
means - has top precedence so it will solved first
reduced to if(0||(b&&c)||a){}
then && has higher precedence so
reduced to if(0||false||a)
then the associativity is left to right so
reduced to if(false||a)
that is(false||2)
return true
In almost every programming language as far as I know 0 means false and 1 means true.
So coming up to your question: you have used && and || operators. Both of these are called Logical operators.
Now first block of yours is a-2||b :-
2-2||-1 so 0||-1. Now since the right expression of || is -1 the or operator will return 1 i.e. True because one of the values of 0 and -1 is non-zero 0 i.e. -1.
Therefore the expression resolves to 1&&c||a :-
Now c=0, therefore 1&&0 returns a 0 because && will only return 1 if both the expressions right and left of it are non zero.
So expression becomes 0||2 :-
Now since || (or operator) requires only one of operands either on right or left side to be non zero hence 0||2 returns 1.
Now your if (a-2||b&&c||a) statement resolves to
if (1)
{
printf("True\n"); }
else......
Therefore since 1 means TRUE the if statement will execute and you will get output as True.

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.

Resources