C#
If statement
condition evaluation
programming logic
execution order

Execution order of conditions in C If statement

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

The order of conditions in a C if statement affects correctness, not just readability. In C, the logical operators && and || evaluate from left to right and short-circuit when the result is already known. That behavior is extremely useful for guarding risky expressions, but it only helps if the conditions are written in the right order.

&& and || Evaluate Left to Right

When two conditions are joined with &&, the left operand is evaluated first. If it is false, the right operand is not evaluated because the whole expression can no longer become true. || behaves similarly in the other direction: if the left side is true, the right side is skipped.

c
1#include <stdio.h>
2
3int first(void) {
4    puts("first");
5    return 0;
6}
7
8int second(void) {
9    puts("second");
10    return 1;
11}
12
13int main(void) {
14    if (first() && second()) {
15        puts("both true");
16    }
17    return 0;
18}

This program prints only first, because the call to second() is skipped once the left side is false.

Short-Circuiting Is a Safety Tool

The classic use case is protecting a dangerous access with a cheap guard. For example, you must check a pointer before dereferencing it.

c
1#include <stdio.h>
2
3int main(void) {
4    const char *text = "demo";
5
6    if (text != NULL && text[0] == 'd') {
7        puts("starts with d");
8    }
9
10    return 0;
11}

If you reverse the order and read text[0] first, the code becomes unsafe when text is NULL. Short-circuit evaluation exists specifically so these guard patterns can be written safely.

Do Not Confuse && With &

Another important distinction is between logical and bitwise operators. && short-circuits. & does not.

c
1#include <stdio.h>
2
3int expensive_check(void) {
4    puts("expensive");
5    return 1;
6}
7
8int main(void) {
9    int ready = 0;
10
11    if (ready && expensive_check()) {
12        puts("logical");
13    }
14
15    if (ready & expensive_check()) {
16        puts("bitwise");
17    }
18
19    return 0;
20}

In the second condition, expensive_check() still runs even though ready is zero. That can hurt performance and cause incorrect behavior if the right side has side effects.

Keep Side Effects Out of Conditions

Conditions are much easier to reason about when they only compute truth values. Once you mix mutation or logging into the operands, short-circuit behavior can make the code harder to predict.

c
1#include <stdio.h>
2
3int counter = 0;
4
5int increment_and_check(void) {
6    counter++;
7    return counter > 1;
8}
9
10int main(void) {
11    if (0 && increment_and_check()) {
12    }
13
14    printf("%d\n", counter);
15    return 0;
16}

The counter remains zero because the function is never called. That is correct according to the language rules, but it can surprise people when the function was secretly doing work that the rest of the program depended on.

Remember That Not All Evaluation Order Is Defined

Within && and ||, C gives you left-to-right evaluation with short-circuiting. Outside those operators, C is less generous. Many expressions do not guarantee the order in which subexpressions are evaluated.

That is why it is dangerous to generalize too far from if (a && b) and assume every compound expression in C behaves the same way. The safe lesson is narrow and important: logical && and || have well-defined left-to-right short-circuit behavior, and you should use that fact deliberately for guards.

Common Pitfalls

The most common mistake is putting the risky expression before the guard that should protect it. Another is using & or | when the code really needs short-circuiting. Teams also create confusing bugs by hiding side effects inside condition operands and then forgetting that later operands might never run. When a condition both checks state and mutates state, maintenance gets much harder because the skipped branch is invisible at a glance.

Summary

  • In C, && and || evaluate from left to right.
  • Both logical operators short-circuit when the result is already known.
  • Put cheap safety checks before any expression that could be invalid or expensive.
  • Do not confuse logical operators with bitwise & and |.
  • Keep side effects out of conditions whenever possible.

Course illustration
Course illustration

All Rights Reserved.