为什么 gcc 不检测所有已处理的枚举值?

Why doesn't gcc detect all enum vals handled?

我有一些 C++ 代码,我在其中切换枚举中的值。我试图用 -Wall -Wextra -Werror 编译它。这在使用 clang 时很好。然而,GCC 抱怨默认的代码路径没有被覆盖。简化版本如下所示:

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);
    }
}

我可以通过在函数末尾添加默认情况或另一个 return 语句来处理此问题。但是,我的问题是为什么 GCC 没有检测到枚举的所有情况都被涵盖了?或者换句话说,GCC 在这里抱怨是否有正当理由?

我比较了编译器输出 here

因为所有情况都没有涵盖。

可以为 val 分配一个未在 Types 定义中命名的值。枚举不限于只是那些值。

some_logic((Types)3);  // whoops

如果您真的非常确定 some_logic 只会提供您在 Types 定义中命名的值,或者希望将其他情况视为 "exceptional"违反先决条件,没关系,但您仍然需要告诉计算机。

Opinion varies on the best approach,但在这种情况下,我将省略 default(这样,如果您稍后添加到 Types 并忘记更新 switch) 但之后会发出一个简单的 throw:

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");
}

在没有任何更强的要求的情况下。