What is short-circuit evaluation in C?
Asked Answered
B

3

9

I'm studying C from A Book on C by Kelley-Pohl, and there's this exercise that I don't understand:

int a = 0, b = 0, x;

x = 0 && (a = b = 777);
printf("%d %d %d\n", a, b, x);
x = 777 || (a = ++b);
printf("%d %d %d\n", a, b, x);

They just say to imagine the output and compare it to the real one. I thought the output would have been

777 777 0

778 778 1

but it is

0 0 0

0 0 1

Broderickbrodeur answered 23/8, 2017 at 20:35 Comment(5)
Well, the answer is in the title of your question. What is confusing you?Eakin
What is your understanding of short-circuit evaluation?Underproduction
What is “short-circuiting” in C like languages?Olimpia
You're right sorry, my english is bad so I didn't really understand Wikipedia. Thanks everyoneBroderickbrodeur
Related:#31437595Davison
D
8

The && operator uses lazy evaluation. If either side of the && operator is false, then the whole expression is false.

C checks the truth value of the left hand side of the operator, which in your case is 0. Since 0 is false in c, then the right hand side expression of the operation, (a = b = 777), is never evaluated.

The second case is similar, except that || returns true if the left hand side expression returns true. Also remember that in c, anything that is not 0 is considered true.

Hope this helps.

Doggett answered 23/8, 2017 at 20:42 Comment(1)
The other key things to remember are that assignment has very low precedence (only the comma operator is lower) and that a || b evaluates to 0 or 1.Samiel
H
13

From the C Standard (6.5.13 Logical AND operator)

3 The && operator shall yield 1 if both of its operands compare unequal to 0; otherwise, it yields 0. The result has type int.

and

4 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.

In this expression statement

x = 0 && (a = b = 777);

the first operand compares equal to 0. So the second operand is not evaluated that is the values of the variables a and b are not changed. So the variable x will be set to 0 according to the paragraph #3 of the section.

From the C Standard (6.5.14 Logical OR operator)

3 The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it yields 0. The result has type int.

and

4 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 this expression statement

x = 777 || (a = ++b);

the first operand compares unequal to 0. So the second operand is not evaluated that is the values of the variables a and b are not changed.. So the variable x will be set to 1 according to the paragraph #3 of the section.

If you will change the order of the operands in the expressions like

x = (a = b = 777) && 0;
x = (a = ++b) || 777;

you get the expected by you result.

Heteronomous answered 23/8, 2017 at 21:3 Comment(0)
D
8

The && operator uses lazy evaluation. If either side of the && operator is false, then the whole expression is false.

C checks the truth value of the left hand side of the operator, which in your case is 0. Since 0 is false in c, then the right hand side expression of the operation, (a = b = 777), is never evaluated.

The second case is similar, except that || returns true if the left hand side expression returns true. Also remember that in c, anything that is not 0 is considered true.

Hope this helps.

Doggett answered 23/8, 2017 at 20:42 Comment(1)
The other key things to remember are that assignment has very low precedence (only the comma operator is lower) and that a || b evaluates to 0 or 1.Samiel
M
0

Another trap in this expression is that; the precendence of the operators. Such as &&, || (logical and, logical or) operators have higher precedence to the assignment operator(=).

in this case x=(0&&(a=b=777)) is same as x=0&&(a=b=777), however x=(0&(a=b=777)) is more readable than the previous one.

Logical operators select one of their operands and returns the result accordingly. They also force their operands to be boolean as true or false. In this expression "x=0&&(a=b=777)" since the first operand is false the result will be equal to first operand.Second operand is short circuited and will not be executed.So the output will be a=b=0, x=0.

x=777 || (a=++b) in this expression since the first operand is true the result will be equal to the first operand and logical operator will not check the second operand, logical OR operator will bypass the second operand.In this expression since the first operand is true (777 is converted to true) the result will be True means x=1.Since the second operand is skipped "a" and "b" values will remain same as their previous values, in this case 0,0

Madden answered 19/3, 2022 at 2:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.