代码之家  ›  专栏  ›  技术社区  ›  dfreese

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

  •  0
  • dfreese  · 技术社区  · 6 年前

    我有一些c++代码,可以在其中切换枚举中的值。我试图用-Wall-Wextra-Werror编译这个。这在使用叮当声时很好。然而,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);
        }
    }
    

    我可以通过在函数末尾添加一个默认case或另一个return语句来处理这个问题。然而,我的问题是,为什么GCC没有检测到enum的所有情况都被覆盖?或者用不同的措辞,GCC是否有合理的理由在这里投诉?

    我比较了编译器的输出 here

    1 回复  |  直到 6 年前
        1
  •  5
  •   Lightness Races in Orbit    6 年前

    因为所有的案子 不是的 已覆盖。

    可以分配给 val 中未命名的值 Types 释义枚举不限于 只是 这些价值观。

    some_logic((Types)3);  // whoops
    

    如果你真的非常确定 some_logic 将只提供您在中指定的值 类型 定义,或者希望将其他情况视为“例外”前提条件违反,这很好,但您仍然需要告诉计算机。

    Opinion varies on the best approach ,但在这种情况下,我会省略 default (这样,如果以后添加到 类型 忘记更新 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");
    }
    

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