Skip to content

Ch5: Flow Control

TL;DR: Conditional Programming: C++ provides if, else, switch, and ternary operators (? :) to execute different branches based on runtime or compile-time conditions.

โšก Quick Reference

#include <iostream>

int main() {
    int a = 10;
    int b = 20;

    // if (condition) - Execute a block when condition evaluates to true.
    if (a < b) {
        std::cout << "a is less" << std::endl;
    }
    // if (!condition) - Test the negation of a condition.
    if (!(a > b)) {
        // nested if - Layer conditions.
        if (a == 10) {
            std::cout << "a is 10" << std::endl;
        }
    }

    // if (condition) else - Compact two-way branching.
    if (a > b) {
        std::cout << "a > b" << std::endl;
    } else {
        std::cout << "a <= b" << std::endl;
    }

    // else if (condition) - Chain multiple mutually exclusive conditions.
    if (a == b) {
        std::cout << "equal" << std::endl;
    } else if (a < b) {
        std::cout << "less" << std::endl;
    }

    // switch (expr) - Compact multi-way branching on integral/enum types.
    switch (a) {
        case 10:
            std::cout << "ten" << std::endl;
            break;
        default:
            break;
    }

    // (condition) ? expression1 : expression2 - Ternary operator.
    int max = (a > b) ? a : b;

    // if (init; condition) - Scoped initializer for if statement (C++17).
    if (int temp = a + b; temp > 15) {
        std::cout << "temp > 15" << std::endl;
    }

    // switch (init; expr) - Scoped initializer for switch statement (C++17).
    switch (int key = a * 2; key) {
        case 20:
            break;
    }

    // if constexpr (condition) - Compile-time branch evaluation (C++17).
    if constexpr (sizeof(int) == 4) {
        std::cout << "32-bit int" << std::endl;
    }

    return 0;
}

๐Ÿง  Core Concepts

  • Conditional Programming: C++ provides if, else, switch, and ternary operators (? :) to execute different branches based on runtime or compile-time conditions.
  • Short-Circuit Evaluation: In logical && and ||, evaluation stops as soon as the outcome is determined, skipping any remaining operands or function calls.
  • Scoped & Compile-Time Control: C++17 introduces scoped initializers for if and switch statements, and if constexpr for compile-time branch selection.

โš ๏ธ Pitfalls (Quick Scan)

Mistake Fix
Using assignment (=) instead of equality (==) Always use == for comparisons and compile with warnings enabled
Omitting a break statement in switch cases Add break; at the end of each case block unless deliberate fallthrough is documented
Using non-integral/non-enum types in switch Use if-else if chains or convert strings to enums/integrals
Incompatible operand types in ternary operator Cast operands explicitly to a common type before using ternary
Relying on implicit promotion inside ternary operator Be explicit with types or use auto to capture deduced type
Accessing scoped variables outside of if/switch blocks Declare variables in the outer scope if their values are needed later
Declaring variables across switch case labels Wrap case block code in braces {} to scope declarations to a single case
Forgetting that matching checks stop at first true condition Structure conditions in correct priority or use separate if statements
Using short-circuit operators with side-effect functions Execute functions and store their results in variables before evaluating conditions
Writing invalid templates in discarded if constexpr branches Ensure all code in discarded branches is syntactically valid

๐Ÿ“– Full Details

Cause โ†’ Effect โ†’ Fix with timestamp (click to expand) * **Using assignment (`=`) instead of equality (`==`)** -> **Condition evaluates to the assigned value, executing the block unexpectedly** -> **Always use `==` for comparisons and compile with warnings enabled (09:58)** * **Omitting a `break` statement in switch cases** -> **Execution falls through into subsequent cases, running unintended code** -> **Add `break;` at the end of each case block unless deliberate fallthrough is documented (15:18)** * **Using non-integral/non-enum types in `switch`** -> **Compile-time error because switch expressions only support integral types** -> **Use `if`-`else if` chains or convert strings to enums/integrals (17:00)** * **Incompatible operand types in ternary operator** -> **Compile-time error because ternary options must evaluate to the same type** -> **Cast operands explicitly to a common type before using ternary (20:09)** * **Relying on implicit promotion inside ternary operator** -> **Incompatible types cause compiler to implicitly promote values (e.g., `int` to `float`)** -> **Be explicit with types or use `auto` to capture deduced type (21:00)** * **Accessing scoped variables outside of `if`/`switch` blocks** -> **Compile-time scope error because variable is destroyed when block exits** -> **Declare variables in the outer scope if their values are needed later (22:00, 10:11)** * **Declaring variables across switch case labels** -> **Skipped constructor initialization leads to compile errors or undefined behavior** -> **Wrap case block code in braces `{}` to scope declarations to a single case (10:12)** * **Forgetting that matching checks stop at first true condition** -> **Subsequent `else if` blocks are ignored even if their conditions are true** -> **Structure conditions in correct priority or use separate `if` statements (08:40)** * **Using short-circuit operators with side-effect functions** -> **Subsequent functions in logical statements are skipped if outcome is determined early** -> **Execute functions and store their results in variables before evaluating conditions (13:00)** * **Writing invalid templates in discarded `if constexpr` branches** -> **Compile-time error because dead template code is still syntactically checked** -> **Ensure all code in discarded branches is syntactically valid (10:08)**

๐Ÿ“Ž Repo Files

  • 10.FlowControl/10.2IfStatements/main.cpp
  • 10.FlowControl/10.3ElseIf/main.cpp
  • 10.FlowControl/10.4Switch/main.cpp
  • 10.FlowControl/10.5ShortCircuitEvaluation/main.cpp
  • 10.FlowControl/10.6IntegralLogicConditions/main.cpp
  • 10.FlowControl/10.7TernaryOperators/main.cpp
  • 10.FlowControl/10.8IfConstexpr/main.cpp
  • 10.FlowControl/10.9IfWithInitializer/main.cpp
  • 10.FlowControl/10.10SwitchWithInitializer/main.cpp
  • 10.FlowControl/10.11VariableScopeRevisited/main.cpp
  • 10.FlowControl/10.12SwitchScope/main.cpp