Search code examples
c++gccclang++gcc-warning

Why doesn't gcc detect all enum vals handled?


I have some c++ code where I switch over values in an enum. I was trying to compile this with -Wall -Wextra -Werror. This is fine when using clang. GCC, however, complains that the default code path is not covered. A simplified version looks as follows:

enum class Types: int {
    A,
    B,
    C
};

bool some_logic(Types val) {
    switch (val) {
        case Types::A:
            return (false);
        case Types::B:
            return (true);
        case Types::C:
            return (false);
    }
}

I can handle this by adding a default case, or another return statement at the end of the function. However, my question was why doesn't GCC detect that all of the cases of the enum are covered? Or phrased differently, is there a legitimate reason for GCC to complain here?

I've put a comparison of the compiler outputs here.


Solution

  • Because all the cases aren't covered.

    It is possible to assign to val a value that is not named in the Types definition. Enums aren't constrained to just those values.

    some_logic((Types)3);  // whoops
    

    If you're really, properly sure that some_logic will only be provided a value that you named in the Types definition, or wish to consider other cases to be "exceptional" precondition violations, that's fine but you'll still need to tell the computer that.

    Opinion varies on the best approach, but in this case I'd leave out the default (so that you still get compiler warnings if you later add to Types and forget to update the switch) but plonk a simple throw afterwards:

    bool some_logic(const Types val)
    {
        switch (val) {
            case Types::A:
                return (false);
            case Types::B:
                return (true);
            case Types::C:
                return (false);
        }
    
        throw std::runtime_error("Didn't expect that innit");
    }
    

    in the absence of any stronger requirements.