c++ - 打开枚举时的编译器警告

标签 c++ visual-c++-2008

enum ENUM(Option1,Option2,Option3);

string func(ENUM x)
{
 switch(x)
 {
  case Option1: return "Option1";
  case Option2: return "Option2";
  case Option3: return "Option3";
 }
}

这可以编译并运行,但会给出一个编译器警告,提示并非所有控制路径都返回。但是,如果您正确使用枚举,情况并非如此,这不是重点吗?如果添加另一个 ENUM val,我希望编译失败,但只要涵盖所有情况,我希望它编译时没有警告。

这是防止错误转换值的编译器吗,它只是 C++ 的一部分并且需要忍受吗?

最佳答案

在 C++ 中,枚举是不安全的。您不能期望枚举值是枚举声明中定义的值之一:

  • 它可能未初始化(因此是垃圾)
  • 您可能有来自 int 的不正确的 static_cast

因此,即使您覆盖了枚举的所有元素,编译器也不能期望开关返回。但是,从功能上讲,这确实是一个错误条件。

有两种 react 方式:

  • default 案例添加到您的enum
  • 在switch之后添加语句

为了明智地选择,请记住编译器可能(如果您要求的话)在 switch 未涵盖 enum 的所有情况时触发警告,在没有 default 语句的情况下。智能编译器(即 Clang)允许将警告分别映射到错误,这极大地有助于捕获这些错误。

因此,您可以做出以下决定:

  • 如果您想在更新枚举后忘记更改此方法时收到通知,请不要使用default
  • 如果您希望能够更新枚举并忽略此开关,请使用默认

最后,您必须决定如何使用react,注意使用运行时错误与使用默认语句不一致(最好尽可能在编译时捕获错误):

  • 忽略错误并返回一些预定义的值
  • 抛出异常(请使用枚举值)
  • 断言(因此在调试中严重崩溃,获取内存转储,并在发布时做其他事情,比如什么都不做,或者抛出异常)

我个人最喜欢的是 UNREACHABLE(Text_) 宏,它会在 Debug 中引发内存转储(以便我获得完整的跟踪)并记录错误并在 Release 中抛出(以便服务器停止处理此请求,但不会完全停止响应)。

这给出了这样的代码:

char const* func(ENUM x)
{
 switch(x)
 {
  case Option1: return "Option1";
  case Option2: return "Option2";
  case Option3: return "Option3";
 }
 UNREACHABLE("func(ENUM)")
}

关于c++ - 打开枚举时的编译器警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5935643/

相关文章:

c++ - 我如何在不提供给/dev/null的情况下使libcurl的输出静音?

c++ - Makefile:为什么这种自动生成先决条件的方法有效?

c++ - VC9 中的字符串流错误? "Cannot access private member"

c++ - "Cannot convert parameter"使用 boost::variant 迭代器

python - 带有 mod_wsgi 的 Apache24-x86-VC9 说, "AH00419: master_main: create child process failed. Exiting."并且不会启动

c++ - 参数包函数参数可以默认吗?

c++ - 在函数声明之后声明一个整数有什么用?

java - android - [linphone] 找不到 "libgnuSTL_shared.so"

php - 使用 Visual Studio 2008 编译 php 扩展,MODULE ID 与 php 不匹配

c++ - 重新初始化结构的成员