我想将我的应用程序切换到LARGEADDRESSAWARE
. 需要注意的问题之一是指针算术,因为指针差异不能再表示为有符号 32b。
有没有办法在大型 C++ 项目中自动查找所有指针减法实例?
如果没有,是否有一些“最省力”的手动或半自动方法来实现这一目标?
我想将我的应用程序切换到LARGEADDRESSAWARE
. 需要注意的问题之一是指针算术,因为指针差异不能再表示为有符号 32b。
有没有办法在大型 C++ 项目中自动查找所有指针减法实例?
如果没有,是否有一些“最省力”的手动或半自动方法来实现这一目标?
PC-Lint 可以发现这类问题。
查看http://gimpel-online.com/MsgRef.html,错误代码 947:
应用于指针的减法运算符 - 发现 p - q 形式的表达式,其中 p 和 q 都是指针。这在最大指针可能溢出保存指针差异的类型的情况下特别重要。例如,假设最大指针为 3 GB -1,指针差异由 long 表示,其中最大 long 为 2 GB -1。请注意,这两个量都适合 32 位字。然后从一个非常大的指针中减去一个小指针将在 long 中产生一个明显的负值,表示指针差异。相反,从一个小指针中减去一个非常大的指针可以产生一个正数。
使用 64 位编译器编译代码并打开 Wp64。
因为指针是 64 位宽,但 int、long、DWORD 等保持 32 位宽,您会收到将 ptrdiff_t 短接为 int32_t 的警告
如果您有 2 个相距超过 20 亿字节 (2GB) 的指针,这只是一个问题。这意味着您:
所以寻找这些特殊情况。
我认为在大多数情况下这不是问题。
由于我们的代码已经用 GCC 编译,我认为最快的方法可能是:
以下是为此需要对 GCC 进行的更改的概要:
将您的警告添加到:
pointer_diff
函数)pointer_diff
函数)。除了直接检测指针减法之外,另一件事可以是检测首先将指针转换为整数类型然后将它们相减的情况。这可能会更困难,具体取决于您的代码结构,以防 regexp 搜索 ( .intptr_t)。-.*-(.*intptr_t) 工作得很好。
不管它值多少钱,我浏览了VS2017 的 Microsoft 编译器警告文档,并搜索了所有涉及“签名”、“trunc”(截断)和“conv”(转换)的警告,它们高于警告级别 1。然后我通过 propsheet 为我们解决方案中的所有项目显式启用这些警告。要启用特定警告,请转到“C/C++ / 命令行 / 附加选项”并以 /wL#### 格式添加它们,其中 L 是您要为其分配的警告级别,#### 是警告编号。
所以我想出了这个列表:
/ w14365 / w14018 / w14146 / w14245 / w14092 / w14287 / w14308 / w14388 / w14389 / w14757 / w14807 / w14302 / w14305 / w14306 / w14307 / w14308 / w14309 / w14310 / w14311 / w14312 / w14051 / w14055 / w14152 / w14239 / w14223 /w14242 /w14243 /w14244 /w14254 /w14267 /w14333 /w14334 /w14367 /w14686 /w14826
请注意,我使用 /w1 是因为我们的全局警告级别已经下降到 1(不要评判我,这是遗留问题)。因此,当您将默认警告级别设置为 3 或更高时,其中一些警告已经启用。
这导致了超过 88000 个警告,其中大部分是关于在使用 STL 的代码中使用 int 而不是 size_t 以及关于 Windows API 类型(如句柄、WPARAM 和 UINT_PTR 等)的转换。我只在 3rd 方库中发现了一些与实际指针算术相关的警告,但在上下文中看起来还不错。
无论如何,我认为这个相关警告列表可能会对某人有所帮助。
此外,使用此答案中描述的工具:https ://stackoverflow.com/a/22745579/9635694
另一种选择是根据CppCoreGuideLines运行内置代码分析。转到“主菜单/分析/配置代码分析/解决方案”并为您要分析的所有项目选择“C++核心检查原始指针规则”。然后“主菜单/分析/运行代码分析/解决方案”。当心:修改您的项目,需要很长时间才能构建并且可能会产生大量警告。您可能想专注于 C26481“不要使用指针算术”和 C26485“无数组到指针衰减”。