【问题标题】:Why is C4062 Visual C++ warning off by default?为什么默认情况下 C4062 Visual C++ 警告关闭?
【发布时间】:2011-10-27 13:54:20
【问题描述】:

根据 MSDN,Visual C++ 可以在何时发出C4062 warning

  • 和枚举用于switch
  • 该枚举的至少一个元素没有标签,并且
  • switch 中没有 default: 标签

现在对我来说,这种情况当然值得警告 - 有问题的元素很可能处理不当。如果不需要对某些元素执行任何操作 - 开发人员可以提供空的 casedefault

这个警告默认关闭的原因是什么?

【问题讨论】:

  • 一个疯狂的猜测是,启用它会破坏 Microsoft 标头中的代码。在我的一个中等大小的 C++ 项目上启用 /Wall 会产生来自 MS 标头的 9812 个警告 (!)。
  • 标准中是否定义了任何警告,或者它们始终是实现定义的。
  • @rerun:好问题(其答案可能很微妙)。如果您对答案感兴趣,请单独提出问题。
  • 我完全同意@AlexandreC。微软痴迷于向后兼容性,有时它可能是一个严重的 PITA。
  • @John Dibling:我试过/Wall - 我不喜欢它。

标签: c++ visual-c++ compiler-construction switch-statement compiler-warnings


【解决方案1】:

有些人(包括我自己)喜欢在构建时看到“0 警告”。如果您只是不处理几个案例,添加一个空案例可能没问题,但是如果您正在使用输入库,它会为您提供一个显示哪个键被关闭的枚举,您真的想要 200 多个空案例您不处理的密钥?

当然,你可能会说只是添加一个空的默认情况,但是:

  • 在上述情况下,它并没有真正意义上的语义
  • 现在你只是邀请C4061(这一切都结束了吗?)

所以如果我默认收到这些警告,它真的会让我的强迫症处于边缘状态

【讨论】:

  • 公平地说,我认为 C4061 没有理由存在。
  • 实际上,我收回了;我可以看到您扩展了枚举并希望确保新成员不会在默认块中表现不佳的情况。不过,它肯定会默认关闭。
  • 给它一些想法,我什至会说 4061 通过更通用更有用,您的代码可能会出现错误,无法处理default错误处理.仍然认为默认关闭是正确的,它是一种调试工具,并非每个人都需要使用。
【解决方案2】:

如果此警告默认为 ON,则 enums 可能无法始终保持可扩展性,无需编辑现有(已经工作的)代码。例如

// (c) 2009
// header.h
enum E { a, b, c };
...
// legacy.cpp
switch(e)
{
case a:  ...
case b:  ...
case c:  ...
}

假设,在 2 年后,开发人员只编辑了 header.h。实现文件经过良好测试,未更改 (legacy.cpp)

// (c) 2011
// header.h
enum E { a, b, c, d, e };  // added 'd','e'

由于强制警告,legacy.cpp 可能会在 de 未处理的地方被警告淹没,这可能是不可取的。

【讨论】:

  • 通常,尤其是在处理遗留代码时,此警告对于捕捉潜在错误非常有帮助。所以,我会考虑将其作为一项功能启用,而不是问题。
  • 查看@Guy Cook 对硬币另一面的回答。
  • 如果您更改了 E,您可能会更改设计意图。我认为这是发出警告的原因,而不是省略。
  • @Tom:关键词是“潜在地”。根据枚举的使用方式,它可能是也可能不是问题。如果这是一个问题,请打开它并仔细检查。如果没有,那就把它关掉,继续你的一天。
  • @Dennis 期望组织中的每个开发人员偶尔打开随机警告是如此乐观以至于其故意疏忽。审查每日构建可能更站得住脚。
【解决方案3】:

这些警告可能意味着要根据具体情况启用。尝试使用 /Wall 编译 C++ 项目会从 Microsoft 自己的标头中产生数千条警告。

现在,您正在尝试调试一大段代码,其中您怀疑某处缺少case 语句(或者您想排除这个假设)。然后启用 C4062。

如果你看起来不错,所有这些禁用的警告都是非常迂腐的,但它们可以用来追踪晦涩的错误。你真的要启用C4264 吗?

【讨论】:

    【解决方案4】:

    人们出于不同的原因使用枚举。

    许多其他人(显然包括微软)会以更少的审查意图使用它们。它们只是一个命名值,它们的分组不是很有趣。在他们的防守中,他们有很多地方可以覆盖。

    有一些像 GuyCook 的例子这样的边缘案例,没有人会对收到警告感到高兴。他是对的,没有人愿意看那些废话。在这种情况下,我将处理代码放在它自己的 cpp 文件中,因此如果不更改标头就不会重新编译它。我希望有更方便的方法来解决这个问题,但我认为没有。

    我很欣赏语言(C#/Java?),因为它们能够忽略带有注释的警告的特定实例。

    您对它的遗漏感到困惑,这意味着您可能正在以它们在设计中最有意义的方式使用它们。我个人认为在耦合和内聚方面应该对枚举进行与类相同的审查。如果有人更改了枚举,则应审查代码。如果有人更改了您继承的类的接口,您会想知道这一点,不是吗?

    但他们没有以这种方式使用它们。枚举只是一种工具,有些人更喜欢将它用作东西的同义词。 :)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-06
      • 2015-05-11
      相关资源
      最近更新 更多