Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do logical operators in C not evaluate the entire expression when it's not necessary to?

I was reading my textbook for my computer architecture class and I came across this statement.

A second important distinction between the logical operators '&&' and '||' versus their bit-level counterparts '&' and '|' is that the logical operators do not evaluate their second argument if the result of the expression can be determined by evaluating the first argument. Thus, for example, the expression a && 5/a will never cause a division by zero, and the expression p && *p++ will never cause the dereferencing of a null pointer. (Computer Systems: A Programmer's Perspective by Bryant and O'Hallaron, 3rd Edition, p. 57)

My question is why do logical operators in C behave like that? Using the author's example of a && 5/a, wouldn't C need to evaluate the whole expression because && requires both predicates to be true? Without loss of generality, my same question applies to his second example.

like image 592
user2020493 Avatar asked Sep 21 '16 10:09

user2020493


People also ask

What does the logical operator not do?

The logical NOT ( ! ) operator (logical complement, negation) takes truth to falsity and vice versa. It is typically used with boolean (logical) values. When used with non-Boolean values, it returns false if its single operand can be converted to true ; otherwise, returns true .

How does logical operators work in C?

The logical-AND operator produces the value 1 if both operands have nonzero values. If either operand is equal to 0, the result is 0. If the first operand of a logical-AND operation is equal to 0, the second operand isn't evaluated. The logical-OR operator performs an inclusive-OR operation on its operands.

What is the logical operator to evaluate a condition to true when it does not equal a value?

Not equals tests whether two values are unequal, so TRUE != FALSE evaluates to TRUE. Like the equality operator, != can also be used with numbers.

Are logical operators in the C language evaluated with the?

Do logical operators in the C language are evaluated with the short circuit? Explanation: None.


2 Answers

Short-circuiting is a performance enhancement that happens to be useful for other purposes.

You say "wouldn't C need to evaluate the whole expression because && requires both predicates to be true?" But think about it. If the left hand side of the && is false, does it matter what the right hand side evaluates to? false && true or false && false, the result is the same: false.

So when the left hand side of an && is determined to be false, or the left hand side of a || is determined to be true, the value on the right doesn't matter, and can be skipped. This makes the code faster by removing the need to evaluate a potentially expensive second test. Imagine if the right-hand side called a function that scanned a whole file for a given string? Wouldn't you want that test skipped if the first test meant you already knew the combined answer?

C decided to go beyond guaranteeing short-circuiting to guaranteeing order of evaluation because it means safety tests like the one you provide are possible. As long as the tests are idempotent, or the side-effects are intended to occur only when not short-circuited, this feature is desirable.

like image 117
ShadowRanger Avatar answered Nov 14 '22 23:11

ShadowRanger


A typical example is a null-pointer check:

if(ptr != NULL && ptr->value) {
    ....
}

Without short-circuit-evaluation, this would cause an error when the null-pointer is dereferenced.

The program first checks the left part ptr != NULL. If this evaluates to false, it does not have to evaluate the second part, because it is already clear that the result will be false.

like image 30
alain Avatar answered Nov 14 '22 21:11

alain