由于 LARGEADDRESSAWARE 检测指针算术

发布于 2024-09-06 12:11:38 字数 166 浏览 10 评论 0原文

我想将我的应用程序切换到 LARGEADDRESSAWARE。需要注意的问题之一是指针算术,因为指针差异不再可以表示为有符号 32b。

有没有办法在大型 C++ 项目中自动查找指针减法的所有实例?

如果没有,是否有一些“最省力”的手动或半自动方法如何实现这一目标?

I would like to switch my application to LARGEADDRESSAWARE. One of issues to watch for is pointer arithmetic, as pointer difference can no longer be represented as signed 32b.

Is there some way how to find automatically all instances of pointer subtraction in a large C++ project?

If not, is there some "least effort" manual or semi-automatic method how to achieve this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

淡莣 2024-09-13 12:11:38

PC-Lint可以发现此类问题。

查看 http://gimpel-online.com/MsgRef.html,错误代码 947:

应用于指针的减法运算符
——表达
发现 p - q 形式,其中 p 和 q 都是指针。这是属于
在最大指针可以的情况下特别重要
溢出保存指针差异的类型。例如,
假设最大指针为 3 GB -1,并且
指针差异由 long 表示,其中
最大限度
long 为 2 GB -1。请注意,这两个数量都适合
在 32 位字内。然后减去一个小指针
非常大的指针将在中产生明显的负值
long 代表指针差异。反过来,
用小指针减去非常大的指针可以产生
正数。

PC-Lint can find this kind of problem.

Look at http://gimpel-online.com/MsgRef.html, error code 947:

Subtract operator applied to pointers
-- An expression of the
form p - q was found where both p and q are pointers. This is of
special importance in cases where the maximum pointer can
overflow the type that holds pointer differences. For example,
suppose that the maximum pointer is 3 Gigabytes -1, and that
pointer differences are represented by a long, where the
maximum
long is 2 Gigabytes -1. Note that both of these quantities fit
within a 32 bit word. Then subtracting a small pointer from a
very large pointer will produce an apparent negative value in the
long representing the pointer difference. Conversely,
subtracting a very large pointer from a small pointer can produce
a positive quantity.

花期渐远 2024-09-13 12:11:38

使用 64 位编译器并打开 Wp64 来编译代码。

因为指针是 64 位宽,但 int、long、DWORD 等保持 32 位宽,因此您会收到将 ptrdiff_t 短路为 int32_t 的警告

Compile the code with a 64 bit compiler and Wp64 turned on.

Because pointers are 64bit wide, but int, long, DWORD etc. stay 32 bit wide, you get warnings for shorting a ptrdiff_t to a int32_t

二智少女 2024-09-13 12:11:38

仅当您有 2 个相距超过 20 亿字节 (2GB) 的指针时,这才会出现问题。这意味着您:

  • 要么拥有非常大的数组(> 2GB)
  • ,要么正在减去指向完全不同结构的指针

,因此请寻找这些特殊情况。

我认为在大多数情况下这不是问题。

This is only a problem if you have 2 pointers that are more than 2000 million bytes (2GB) apart. This means that you:

  • either have very large arrays (> 2GB)
  • or you are subtracting pointers that point to totally different structures

So look for these special cases.

I think that in most cases this is not a problem.

简单气质女生网名 2024-09-13 12:11:38

由于我们的代码已经使用 GCC 进行编译,我认为最快的方法可能是:

  • 构建一个 GCC
  • 创建 GCC 的自定义修改,以便在检测到指针减法时打印警告(或错误)
  • 构建项目并收集有关指针减法的所有警告

以下是为此需要对 GCC 进行的更改的概述:

将警告添加到:

  • c-typeck.c (pointer_diff function)
  • cp/typeck.c (pointer_diff > 功能)。

除了直接检测指针减法之外,要做的另一件事是检测首先将指针转换为整型然后减去它们的情况。这可能会更困难,具体取决于代码的结构,在这种情况下,正则表达式搜索 (.intptr_t).-.*-(.*intptr_t) 效果很好。

As our code already compiles with GCC, I think perhaps the fastest way might be:

  • build a GCC
  • create a custom modification of GCC so that it prints warning (or error) whenever pointer subtraction is detected
  • build the project and gather all warnings about pointer subtraction

Here is the outline of changes which need to be done to GCC for this:

Add your warnings into:

  • c-typeck.c (pointer_diff function)
  • cp/typeck.c (pointer_diff function).

Besides of directly detecting pointer subtraction, another thing to do can be to detect cases where you first convert pointers to integral types and then subtract them. This may be more difficult depending on how is your code structured, in out case regexp search for (.intptr_t).-.*-(.*intptr_t) has worked quite well.

烟凡古楼 2024-09-13 12:11:38

无论它的价值如何,我都经历了 VS2017 的 Microsoft 编译器警告文档 并搜索了所有涉及“signed”、“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 等)的转换。我只在第三方库中发现了一些与实际指针算术相关的警告,但这些警告在上下文中看起来没问题。

不管怎样,我认为这个相关警告列表可能会对某人有所帮助。

另外,使用此答案中描述的工具: https://stackoverflow.com/a/22745579/9635694

另一种选择是根据 CppCoreGuideLines 运行内置代码分析。转到“主菜单/分析/配置代码分析/获取解决方案”,然后为所有要分析的项目选择“C++ Core Check Raw Pointer Rules”。然后“主菜单/分析/运行代码分析/寻求解决方案”。注意:修改您的项目,需要很长时间来构建,并且可能会生成大量警告。您可能需要重点关注 C26481“不要使用指针算术”,也许还有 C26485“无数组到指针的衰减”。

For whatever it's worth, I went through the Microsoft compiler warning docs for VS2017 and searched for all warnings referring to "signed", "trunc" (truncation) and "conv" (conversion), which were higher than warning level 1. Then I explicitly enabled those warnings for all projects in our solution via a propsheet. To enable specific warnings, go to "C/C++ / Command Line / Additional Options" and add them in the format /wL####, where L is the warning level you want to assign them to and #### is the warning number.

So what I came up with is this list:

/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

Note that I used /w1 because our global warning level is already down at 1 (don't judge me, it's legacy). So some of these warnings are already enabled when you have set the default warning level of 3 or higher.

This resulted in more than 88000 warnings, most of which were about using int instead of size_t in code using the STL and about conversions regarding Windows API types like handles, WPARAMs and UINT_PTRs and such. I only found a few warnings related to actual pointer arithmetics in a 3rd party library, but those looked alright in context.

Anyway, I thought this list of related warnings might help someone.

Also, use the tools described in this answer: https://stackoverflow.com/a/22745579/9635694

Another option is to run the builtin code analysis according to the CppCoreGuideLines. Go to "Main menu / Analyze / Configure Code Analysis / For Solution" and select "C++ Core Check Raw Pointer Rules" for all the projects you want to analyze. Then "Main menu / Analyze / Run Code Analysis / For Solution". Beware: Modifies your projects, takes a long time to build and might generate a lot of warnings. You might want to concentrate on C26481 "Don't use pointer arithmetics" and perhaps C26485 "No array-to-pointer decay".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文