Skip to content

Conditionals

Joël R. Langlois edited this page Jan 29, 2025 · 6 revisions

No Yoda Conditions

One of many dated practices. Modern compilers and static analysers (which you should be running regularly!) are smart enough to catch improper or unexpected assignments in conditions.

That being said, write in a more English-like structure.

// Do this:
if (x == 0)
    //[...]
// ...not this.
if (0 == x)
    // [...]
// A modern compiler should catch potential mistakes like this:
if (x = 0)
   // [...]

Formatting Rules

If a statement's body spans more than one line, wrap all associated statement bodies in curly braces.

// Do this:
if (foo == "okay")
{
    doSomething();
    updateSomething();
}
else if (bar == "neato")
{
    doSomethingElse();
}
else
{
    logSomething();
}
// ...Not this:
if (foo == "okay")
{
    doSomething();
    updateSomething();
}
else if (bar == "neato")
    doSomethingElse();
else
    logSomething();

But, if all statement bodies are one liners, put them on separate lines and don't use braces.

if (foo == "okay")
    doSomething();
else if (bar == "neato")
    doSomethingElse();
else
    logSomething();

That is, unless you're denoting a consistent and simple pattern.

if (foo == "abc")          return 0;
else if (foo == "defgh")   return 1;
else if (foo == "hijklm")  return 2;

return -1;

Assignment in Condition

The only time it is valid to assign a variable in a condition is to store a temporary pointer. Always assign temporary pointers in the conditional to try and avoid possible null pointer dereferences.

if (auto* instance = getInstance())
    instance->doSomethingImportant();
else
    logMessage ("Something failed.");

Caveat

The C++ standard allows the temporarily created pointer to be accessible in the else if and else, so be diligent!

Single Whitespace Line Rules

If a condition is computed before an if and is comprised of a single line of code, butt the code up against the conditional.

const bool test = somethingHappened() && somethingElseHappened();
if (test)
{
    //Do something important.
}

If a condition is computed before an if and is comprised of multiple lines of code, insert a single line of space before the conditional.

const bool foo = somethingHappened() && somethingElseHappened();
const bool bar = otherStuffHappened() && weNeededMoreChecks();

if (foo && bar)
{
    //Do something important.
}

Multiline Whitespace Rules

Always align the comparison operator at the beginning of the line, and align the operator with the first character of the condition from the previous line:

bool checkStates()
{
    return someCondition
           && someOtherCondition;
}

If the conditions span many lines, align the operators themselves with 1 space before the conditions:

bool checkStates()
{
    return someCondition
        && someOtherCondition
        && exhibitA()
        && exhibitB()
        && exhibitC()
        && exhibitD();
}

Use Early Returns Where Possible

enum MyEnum
{
    componentA = 0,
    componentB,
    componentC,

    defaultValue = -1
};
MyEnum convertStringToMyEnum (const std::string& source)
{
    if (source == "foo")
        return componentA;
    else if (source == "bar")
        return componentB;

    return defaultValue;
}
std::string convertMyEnumToString (MyEnum value)
{
    switch (value)
    {
        case componentA: return "foo";
        case componentB: return "bar";
        case componentC: return "okay";

        default:
        break;
    };

    return std::string();
}