【问题标题】:Dangerous magic number N used使用了危险的幻数 N
【发布时间】:2017-12-25 00:00:35
【问题描述】:

PVS-Studio,静态代码分析器,用于以下代码

size_t const n = 4;
int a[n] = {};

报告:

V112危险的魔法数字4使用:...t const n = 4;. test.cpp 3

尽管 PVS-Studio 与 Visual Studio 2017 项目一起使用,并且针对 32 位和 64 位报告相同的警告,但分析器 AFAIU 并未考虑这些构建配置。

我希望能更好地分析上下文并将上面的代码视为等效

int a[4] = {};

PVS-Studio 不为其发出任何诊断。

在上面的例子中,这个使用了危险的幻数N,是误报吗?

上面两个代码示例没有被分析为等效的原因是什么?

【问题讨论】:

  • 如果有什么我会假设第二个示例使用幻数不如第一个安全,因此更值得警告。似乎该警告与 n = 4 相关,而不是使用 n 作为数组大小。
  • 这一切都在您从 PVS-Studio 获得并发布的链接中进行了解释。甚至为什么int a[4] 没有收到警告。
  • @mloskot 数字 4 在表中被提及为在移植到 64 位时可能会导致问题并需要特别注意的数字之一。 int a[4] 被提及为免于检查的特殊情况。使用 5 作为常量,不会有警告。
  • 或者更好的是suppress this one instance 在发出警告的行之后添加//-V112
  • 静态分析器可能有规则要求 0 或 1 以外的数字是宏;不管与第二种情况的等价性如何。

标签: c++ static-analysis pvs-studio


【解决方案1】:

从 32 位移植到 64 位时,数字 4 被视为潜在危险数字之一,因此警告将 const 分配为 4。其他数字列在您发布的链接后面的表格中。举例说明它是如何危险的。

您可以通过在行尾添加 //-V112 suppress individual warning 确定 100% OK。

size_t const n = 4; //-V112

这将抑制警告,您可以再次专注于您的工作。

至于int a[4] = {}; PVS-Studio 认为它是一种特殊情况,它不会发出警告。为什么在第一种情况下不考虑它,我不知道。但对于真正特定的情况,它看起来像是硬编码的异常。

如果您不构建 64 位版本,那么我认为现在完全禁用警告是安全的。但请注意 - 眼见为实。

【讨论】:

    【解决方案2】:

    这个

    size_t const n = 4;
    int a[n] = {};
    

    是误报。

    64 位诊断非常嘈杂,您对此无能为力。是的,分析器会产生许多误报,例如40xFFFFFFFF 等幻数。在分析器中,当它不抱怨时,已经出现了很多异常(例如:int a[4] = {};)。但是,仍然有很多使用常量的选项,以至于无法预见所有这些选项。

    将代码移植到 64 位系统时,查看所有幻数是有意义的,例如,以确保程序员不会期望指针大小在某处为 4 字节。然后关闭V112 诊断是有意义的,这样它就不会打扰您。

    【讨论】:

    • 您是从哪里想到 64 位的?我在示例行中没有看到它。这可以在 32 位或 16 位系统上。
    • 我已经更新了我的问题以澄清我将 PVS 与 VS2017 一起使用
    • > "你是从哪里想到 64 位的?"此诊断是为检测 64 位问题而创建的。 viva64.com/en/l/0009
    • @AndreyKarpov 你能和上面 MarekVitek 的 cmets 联系起来吗?如果这是正确的,我可以建议将文档重新表述为“让我们列出 PVS-Studio 特别关注的特定幻数......”或类似的东西
    • 我不明白这个问题。幻数(用于检测 64 位问题)是 4、32、0x7FFFFFFF、0x80000000 和 0xFFFFFFFF。
    【解决方案3】:

    阅读您发布的链接后,我认为您的情况是误报。

    该工具假设您将在malloc(或等效分配过程)语句中使用n,使其等于int(或任何4字节变量)的大小。所以推荐使用sizeof(desired type)

    如果您在malloc 语句中使用n,这将是有意义的——因为int(或任何其他类型)可能会因不同的架构而有所不同(如果不是现在,将来也是如此)。但显然这不是你的情况。

    【讨论】:

    • 你如何得到使用 malloc 的假设? OP 正在声明一个自动变量,而不是使用mallocnew。常量标识符可用于赋值或算术表达式。
    • 正如我所说,我的结论是基于我在问题上发布的链接上阅读的内容:viva64.com/en/w/V112/print - 它以malloc 为例进行解释。
    • @ThomasMatthews 因为 PVS-Studio 显然没有在使用变量的地方进行深入分析。它看到 const 被分配 4 并发出警告。但也许我错了。
    猜你喜欢
    • 2011-04-09
    • 1970-01-01
    • 1970-01-01
    • 2018-10-17
    • 1970-01-01
    • 2021-12-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-04
    相关资源
    最近更新 更多