History of the question:
The logical operators && and || were introduced in C to evaluate complex logical conditions. A key feature of their operation is the support of short-circuit evaluation: the second operand is not evaluated if the result can be deterministically known from the first one.
Problem:
Many programmers expect that both operands are always evaluated, or incorrectly use side effects in the second operand, assuming it will always be executed. In practice, this leads to errors, resource leaks, and unexpected behavior.
Solution:
Understanding the mechanism of short-circuit evaluation helps to build safe constructs, especially in pointer checks, resources, and file handling. Using side effects in the right part of an expression is only acceptable if done consciously. Example of a safe check:
if (ptr && ptr->field) { /* ... */ }
Key features:
Will the expression f() be executed in the fragment: if (0 && f())
No, the function f() will not be called because the result is already clear — the expression is false, further evaluation is pointless.
And in the next statement: if (1 || f())?
Again, f() will not be called: the result is already true after the first operand.
Is it possible to use && and || operators to control the order of execution of functions with side effects?
Technically yes, but such control leads to unreadable and unstable code. It is better to explicitly state the order of function calls, without relying on short-circuit behavior for side effects.
if (flag || process()) { // ... }
The process will never be called if the flag is true.
Pros:
Cons:
if (!flag) process();
Pros:
Cons: