【问题标题】:Warnings (or other means) to identify potential unsigned integer overflows用于识别潜在无符号整数溢出的警告(或其他方式)
【发布时间】:2021-09-12 10:14:30
【问题描述】:

在某些情况下,潜在的无符号整数溢出可能会导致问题。这个例子说明了一个:

struct Image
{
    uint32_t width;
    uint32_t height;
    uint32_t depth;
};

void* allocateMemory(size_t);

...

allocateMemory(f.width * f.height * f.depth);

GCC、clang 和 MSVC 的 x64 反汇编表明乘法将使用 32 位算术完成。当乘法列表很长时,这可能会导致溢出。

mov     eax, dword ptr [rdi + 4]
imul    eax, dword ptr [rdi]
imul    eax, dword ptr [rdi + 8]
mov     rdi, rax

这个godbolt链接包含上面的例子和3个流行编译器的反汇编:https://godbolt.org/z/1P1bT3jj6

我在 GCC 和 clang(包括 -Weverything)上启用了所有可能的警告,但没有报告上述代码中的问题。只有 MSVC 在编辑器 (C26451 Arithmetic overflow: Using operator * ...) 中报告了它,但我没有设法让它在构建时报告。

所以问题是如何在构建代码时发现这些类型的问题(没有运行时检查)。有没有可以捕捉到这一点的静态分析工具?或者也许是在使用 MSVC 构建时报告此 Intellisense C26451 警告的方法?

【问题讨论】:

  • 我知道如何解决这个问题。问题是如何知道有问题需要解决。
  • 该标准规定了无符号类型在溢出时会发生什么(即模运算又名“环绕”)。因此,如果可以配置您的编译器(或工具集的某些其他组件)以发出此类警告,那么在标准指定的行为是预期结果的情况下,您想做什么?
  • 就标准而言,没有无符号整数溢出之类的东西。无符号类型实现模运算。在 C++ 中,您可以将整数包装在自定义类中,例如不允许乘法或以更高的宽度执行它,同时传递其他算术运算。

标签: c++ visual-c++ g++ clang++ gcc-warning


【解决方案1】:

对于 MSVC,您可以通过在项目(或文件)的属性中启用“代码分析”1 来启用警告,例如 C26451构建时

或者,您可以使用“构建”菜单中的“运行代码分析”命令(或 Ctrl+Shift+Alt+f7)。


您可以在命令行中使用/analyze 开关启用此选项;但是,您需要指定要使用的代码分析“插件”(随 Visual Studio 提供)(典型的选项是 /analyze:plugin EspxEngine.dll)。在“分析插件选项”部分的this Microsoft web-page 上给出了这些的概述。以下段落似乎特别相关:

在命令行上构建时,可以使用 Esp.Extensions 环境变量来指定 EspXEngine 扩展。为了 例如:
set Esp.Extensions=ConcurrencyCheck.dll;CppCoreCheck.dll;


1 但请注意,此选项会显着增加构建时间,这对于大型项目可能会成为问题。

【讨论】:

  • 知道如何从命令行打开它(我正在使用 CMake)?我相信它是 /analyze,但在 gotbolt 上进行测试并没有改变任何东西。
  • @Pan 嗯。不完全确定。关闭上面显示的选项并在编译器命令行选项中添加/analyze 开关(在真正的 VS 中,而不是在编译器资源管理器中)也不会显示 C26451 警告。可能需要指定一个规则集文件,而在线编译器可能无法使用。
  • @Pan.ChristopoulosCharitos ... 是的!使用 /analyze:plugin EspxEngine.dll 命令行选项有效。
猜你喜欢
  • 1970-01-01
  • 2012-02-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多