问题描述
在某些情况下,潜在的无符号整数溢出可能会导致问题。这个例子说明了一个:
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
警告的方法?
解决方法
对于 MSVC,您可以通过在项目(或文件的)属性中启用“代码分析”来启用警告,例如 C26451 构建1:
或者,您可以随时使用“构建”菜单(或 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 但请注意,此选项会显着增加构建时间,这对于大型项目来说可能会成为问题。