dependent chained-up if-statements [duplicate] - c

This question already has answers here:
Is short-circuiting logical operators mandated? And evaluation order?
(7 answers)
Closed 6 years ago.
Let's take this C-code example:
int ID = 0;
if( (Check(&ID) == ERROR)
||(ID == -1)
){
return ERROR;
}
Do you have any guarantee that (Check(&ID) == ERROR) is checked before (ID == -1) ?
(ID = -1 would be an error-state, set by the function Check)

Yes you do. For an expression of the form x || y, y is only evaluated if x evaluates to 0.
This is called short-circutting, and also applies to &&.
Your parentheses are also superfluous: the same applies to the equivalent (and, in my opinion, clearer)
if (Check(&ID) == ERROR || ID == -1)

Yes, because there is a sequence point between evaluation of first and second operand of || operator.
N1570 5.1.2.3 Program execution, paragraph 3 says:
The presence of a sequence point
between the evaluation of expressions A and B implies that every value computation and
side effect associated with A is sequenced before every value computation and side effect
associated with B.
N1570 6.5.14 Logical OR operator, paragraph 4 says:
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.

Related

How does this trick work? bool && printf() [duplicate]

This question already has answers here:
What is short-circuit evaluation in C?
(3 answers)
Closed last year.
How does this work?
int x = 0;
x && printf("Hello World!");
This will output nothing on terminal, but
int x = 1;
x && printf("Hello World!");
will output "Hello Wolrd!"
It is called short circuit evaluation of a logical expression. Logical expressions are evaluated until the result is undetermined.
In this case:
if x==0 logical AND will be false despite the other side of the
expression. printf will not be called.
if x==1 the result of AND is still undetermined. printf will be called.
The result of this AND operation is not used and compiler will warn you.
The C standard specifies the behavior of && in clause 6.5.13. Paragraph 4 says:
Unlike the bitwise binary & 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 equal to 0, the second operand is not evaluated.

How this logical operator works? [duplicate]

This question already has answers here:
Is short-circuiting logical operators mandated? And evaluation order?
(7 answers)
Closed 1 year ago.
#include<stdio.h>
int main()
{
int a=-10,b=3,c=0,d;
d= a++||++b &&c++;
printf("%d %d %d %d ",a,b,c,d);
}
How above expression is evaluates. I have read preceedence but still i am getting confused. Kindly give me the right solution of this in step by step.
In case of || and && operators the order of evaluation is indeed defined as left-to-right.So, operator precedence rules tell you that the grouping should be
(a++) || ((++b) && (c++))
Now, order-of-evaluation rules tell you that first we evaluate a++, then (if necessary) we evaluate ++b, then (if necessary) we evaluate c++, then we evaluate && and finally we evaluate ||.
I have a feeling this is a homework question, so I'll try to give extra explanation. There are actually a lot of concepts going on here!
Here are the main concepts:
Pre- and post- increment and decrement. ++a increments a before the value is used in an expression, while a++ increments a after the value is used in the expression.
Operator precedence. Specifically, && has higher precedence than ||, which means that the assignment of d should be should be read as d = (a++) || (++b && c++);
Expression evaluation order. The link shows a whole list of evaluation rules for C. In particular, item 2 says (paraphrasing) that for operators || and &&, the entire left side is always fully evaluated before any evaluation of the right-hand side begins. This is important because of...
Short-circuit boolean evaluation, which says that, for operators && and ||, if the value of the left-hand term is enough to determine the result of the expression, then the right-hand term is not evaluated at all.
Behaviour of boolean operators in C. There is no inbuilt boolean type in C, and operators && and || work on integer values. In short, an argument is 'true' if it is nonzero, and false if it equals zero. The return value is 1 for true and 0 for false.
Putting this all together, here is what happens:
After the first line, a is -10, b is 3, c is 0 and d is unset.
Next, the variable d needs to be assigned. To determine the value assigned to d, the left hand term of (a++) || (++b && c++) is evaluated, which is a++. The value USED in the expression is 10, however the value of a after this expression is -9 due to the post-increment.
For the purposes of the boolean operator, the value 10 is true, and therefore value of the || expression is 1. Because of short-circuit evaluation, this means that ++b && c++ is not evaluated at all, so the increments do not happen. Thus we have d = 1.
At the end, the values are: a = -9, b = 3, c = 0, d = 1.
So the program prints out -9 3 0 1.

"And" and "Or" operators in conditionals in C [duplicate]

This question already has answers here:
Is short-circuiting logical operators mandated? And evaluation order?
(7 answers)
Closed 6 years ago.
I always wondered about something and couldn`t find an answer somewhere else. If I have this piece of code:
if ((cond1) &&(cond2) && (cond 3) && (cond 4))
{
// do something
}
Let`s say the first condition is false, then my program will verify the other conditions too, or just skip verifying them?
But if I have
if ((cond1) ||(cond2) || (cond 3) || (cond 4))
{
// do something
}
and cond 1 is true, will my program go instantly on the if part or continue to verify the other conditions too?
Quoting C11 standard, chapter §6.5.13, Logical AND operator (emphasis mine)
Unlike the bitwise binary & 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 equal to 0, the second
operand is not evaluated.
So, if the first condition (LHS operand) evaluates to false, the later conditions, i.e., RHS operand of the && is not evaluated.
Similarly (Ironically, rather), for 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.
In C both && and || "sort-circuit", meaning if evaluation of the left operand is enough to determine the outcome then the right operand is not evaluated.

how do we interpret the `||` and `&&` in an assignment statement? [duplicate]

This question already has answers here:
Evaluation of C expression
(8 answers)
Closed 7 years ago.
I have been coding from a long time though I'm still a student programmer/ I'm usually good at programming but when questions like the one below are asked I get stuck. What will be the output and why of the following program?
int main()
{
int i=4,j=-1,k=0,w,x,y,z;
w=i||j||k;
print("%d",w);
return 0;
}
output:
1
why this result? what does the statement w=||j||k; means?
i || j || k is evaluated from left to right. It does that:
i == 4, which is true, so ORing it with any other value will yield true. That's it1.
The rest of the statement is not evaluated because || and && are short-circuit operators, that is, if in your statement i != 0, neither j nor k will be evaluated because the result is guaranteed to be 1. && works similarly.
That's important to remember if you have something like f() || k(), where k has some side effect like an output to screen or a variable assignment; it might not be executed at all.
The bitwise OR operator | really ORs the bitwise representations of the values instead; it evaluates all its operands.
1 Thanks to #SouravGosh on that!
In your code,
w=i||j||k;
is equivalent to
w= ((i||j) || k);
That means, first the (i||j) will be evaluated, and based on the result (if 0), the later part will be evaluated.
So, in your case, i being 4, (i||j) evaluates to 1 and based on the logical OR operator semantics, the later part is not evaluated and the whole expression yields 1 which is finally assigned to w.
Related quotes, from C11 standard, chapter §6.5.14, Logical OR operator
The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it
yields 0. The result has type int.
then, regarding the evaluation of arguments,
[...] If the first operand compares unequal to 0, the second operand is
not evaluated.
and regarding the grouping,
[...] the || operator guarantees left-to-right evaluation;
The result of boolean operators yields an int value of 0 or 1.
See 6.5.13 and 6.5.14, paragraph 3.
The [...] operator shall yield 1 [or] 0. The result has type int.

Ambiguous operator precedence, please explain why operator predence is not followed here? [duplicate]

This question already has answers here:
Why does "++x || ++y && ++z" calculate "++x" first, even though operator "&&" has higher precedence than "||"
(11 answers)
Closed 9 years ago.
x = y = z = 1;
z = ++x||++y&&++z;
operator precedence is as follows --
(pre-increment) > && > ||
so answer should be--
1. 2||2 && 2
2. 2||1
3. 1
print x,y,z should be 2,2,1
but, answer is 2,1,1.
Precedence is not the same as order of evaluation. Precedence simply determines what operands and operators belong together. The exact order of evaluation is unspecified except with the logical operators, which are evaluated in strict left-to-right order to enable short-circuiting.
So because && has higher precedence, the variables are first grouped as follows:
(++x) || (++y && ++z)
Then, following left-to-right order, ++x is evaluated. Given that ++x is true, it is known that the entire expression is true. So expression evaluation is short-circuited. (++y && ++z) never gets evaluated. Hence y and z never get incremented.
Expressions with logical operators && and || evaluate left to right:
C99, Section 6.5.14-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.
Since x++ is not zero, the expression short-circuits evaluation of everything to the right of ||, including their side effects. That's why only x++ is evaluated, so x becomes 2. The remaining variables stay at 1, as they should.
There's no sequence point in the expression:
z = ++x || ++y && ++z;
between the pre-increment of z and assignment to z.
So, if the ++z is actually evaluated, that puts you instantly into undefined behaviour territory and anything can happen. You are not permitted to modify the same object twice without an intervening sequence point. Annex C (from C99) lists all the sequence points and the controlling one here is following a full-expression (the entire calculation and assignment).
6.5 Expressions /2 states:
Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be read only to determine the value to be stored.
However, given your initial value of x as 1, the ++z part of the expression is not evaluated, in this particular case. That doesn't make the expression itself any less dangerous since it will invoke UB in the case where the starting point is x == -1 and y != -1.
In this case, the controlling part of the standard is 6.5.14 Logical OR operator /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.
So, the ++x is evaluated first and, because it evaluates to not-zero, ++y && ++z is never evaluated. x is incremented to 2 and z is set to the "truthy" value of that, or 1, y remains untouched at 1.

Resources