C/C++ Arena

Step 2 of 7

Status codes

The oldest approach, straight from C: the function returns a status (did it work?), and delivers the actual result through a reference parameter.

#include <iostream>
#include <string>

[[nodiscard]] bool withdraw(int& balance, int amount) {
    if (amount <= 0 || amount > balance) return false;   // refuse, change nothing
    balance -= amount;
    return true;
}

int main() {
    int balance = 100;
    for (int amount : {30, 500, -5, 70}) {
        if (withdraw(balance, amount)) {
            std::cout << "took " << amount << ", left " << balance << "\n";
        } else {
            std::cout << "refused " << amount << "\n";
        }
    }
    // withdraw(balance, 10);   // warning: ignoring return value declared with 'nodiscard'
}
took 30, left 70
refused 500
refused -5
took 70, left 0

How it works

Strengths and weaknesses

It's simple, fast and works everywhere, including C. But the caller must remember to check, the result has to be declared before the call, and a plain bool can't say why it failed. The next steps improve on each of those.

Your task

Division by zero is the failure case: return false and leave out alone. Otherwise store a / b in out and return true. Add [[nodiscard]] before the return type.

Your turn: write [[nodiscard]] bool divide(int a, int b, int& out) that returns false for division by zero and otherwise stores a / b in out.

Previous: Bugs vs expected failures Next: optional for "maybe"