Skip to content
Theory · Conditions · lesson 1 of 6

if, else and initializers in if

The statements in main run in order, from top to bottom. An if statement runs the block in curly braces only when the condition in parentheses is true. The block after else runs when the condition is false:

C++
#include <iostream>

int main() {
    int t = 25;
    if (t < 0) {
        std::cout << "frost\n";
    } else if (t < 20) {
        std::cout << "cool\n";
    } else {
        std::cout << "warm\n";  // warm
    }
}

Each such block is called a branch. An else if chain checks the conditions from top to bottom and runs the first branch whose condition is true, skipping the rest. The final else branch runs when every condition is false. Without it, nothing runs in that case.

Dangling else

Curly braces around a one-statement branch may be left out. But when two if statements are nested without braces, an else can be attached to the wrong if by mistake. The compiler attaches an else to the nearest if that has no else yet, and it ignores indentation:

C++
int x = 5;
if (x > 0)
    if (x > 10)
        std::cout << "big\n";
else  // ✗
    std::cout << "not positive\n";  // not positive

The indentation suggests that the else belongs to if (x > 0), but it actually goes to if (x > 10). That is why the program prints not positive when x is 5. Such an else is called a dangling else. Clang and GCC warn about it, but the code compiles.

Put curly braces around every branch, even a one-line one: then the compiler and the reader see the same branches.

if with an initializer

A variable needed only for the check can be declared right inside the if, before the condition, followed by a semicolon. This part of the if is called an initializer. A variable declared in it is visible in the condition and in every branch of that if:

C++
int n = 2023;
if (int r = n % 4; r == 0) {
    std::cout << "divisible by 4\n";
} else {
    std::cout << "remainder " << r << '\n';  // remainder 3
}

After the if, the variable r no longer exists: using it below does not compile. So the name r does not get in the way of the rest of the function.

Common mistake

A second line with the same indentation is added to a branch without curly braces:

C++
int x = -1;
if (x > 0)
    std::cout << "positive\n";
    std::cout << "checked\n";  // ✗
TEXT
warning: misleading indentation; statement is not part of the previous 'if' [-Wmisleading-indentation]

Without braces, an if controls only the one statement that follows it, and indentation does not change that. So checked is printed for any x, including x = -1. The compiler only warns and builds the program. The fix is curly braces around both lines.