thegreatjedi
thegreatjedi

Reputation: 3038

What's the most appropriate way to handle a switch's case that will never be entered?

Here are some parts of my code:

enum Mode {
    MAIN = 0,
    NUM_GEN,
    ARITH,
    MONEY,
    END_FLAG
}

int main() {
    launchModule(MAIN);

    return 0;
}

void launchModule(Mode mode) {
    ...
    getline(cin, input);
    choice = stoi(input);
    // More input validation

    switch (mode) {
    case MAIN:
        switch (static_cast<MODE>(choice)) {
        // Other cases: Recursively calls launchModule(choice)
        case END_FLAG:
            // Exits current function
            break;
        }
        break;
    // Other cases: no switch(Mode) happens
    case END_FLAG:
    // TODO: What goes here?
        break;
    }
    ...
    return;
}

As seen above, launchModule(mode) is first called by main() with input MAIN, and may recursively call itself with any value of Mode EXCEPT END_FLAG. Therefore, launchModule can be said to never be called with input value END_FLAG. Nonetheless, case END_FLAG exists in the first switch statement block and ought to be handled somehow. In general, what is the appropriate way to handle cases in a switch statement that will never be entered?

It can be assumed here these are the only instances when launchModule() is called.

Upvotes: 0

Views: 101

Answers (1)

Jerry Coffin
Jerry Coffin

Reputation: 490408

Given that it should never be entered, the appropriate response would probably be to throw an exception, assert, or abort execution with an appropriate error message.

Choosing between these can be non-trivial. An assert will be disabled when you compile with NDEBUG defined, which you may not want. Otherwise, it aborts the program immediately (without invoking destructors and such). This tends to make it most appropriate when you want to kill the program quickly when debugging, but might (for example) log and continue executing in released code.

Throwing an exception would be most appropriate if it might be possible to recover from this error, especially for something like server code that must continue executing regardless of what else happens.

Aborting tends to be most appropriate if you're sure this is a truly fatal error that can only happen if something has gone hideously wrong, and attempting to continue execution at that point is likely to destroy data so you want to quit as quickly and noisily as possible (in particular, you want to ensure against destructors running, because they might make a bad situation even worse).

Under the circumstances given here, there's a clear problem internally in the code if this leg of the switch statement is entered. That indicates at least usually you'd be choosing between an assert, or aborting on your own. I'd tend toward the latter, as you probably don't want to inhibit this behavior in released code.

Upvotes: 4

Related Questions