C:在处理 32 位程序时,在 Windows 64 位机器上将 int 转换为 int* 时出现警告

Posted

技术标签:

【中文标题】C:在处理 32 位程序时,在 Windows 64 位机器上将 int 转换为 int* 时出现警告【英文标题】:C: Warning when casting int to int* on Windows 64-bit machine when working on 32-bit program 【发布时间】:2021-02-27 14:42:01 【问题描述】:

我正在开发一个遗留的 32 位程序,其中有很多像 DWORD* a = (DWORD*)b 这样的演员表,其中 b 是本机 int,我收到很多这样的警告:

Cast to 'DWORD *' (aka 'unsigned int*') from smaller integer type 'int' ['clang: -Wint-to-pointer-cast]

由于在编译期间大小相等,这很好,但我不知道 Clang 是如何知道这一点的。除了完全禁用它之外,我还能做些什么来满足这个警告?

编辑:由于我对编译器 Clang 和调用 Clang 的语言服务器 clangd 的误解,问题的前提很糟糕。语言服务器不知道我的目标是 x86。

【问题讨论】:

警告告诉您尺寸相等。如果您正在为 Win64 目标编译,它们确实不会。 Clang 知道这一点,因为它必须为目标生成正确的可执行代码。可能你想告诉 Clang 为 Win32 构建,如果它有一个标志的话。 换句话说:与警告相关的 32 位 vs 64 位的意义不是源代码的功能,而是编译器的功能,构建环境和命令行选项。有问题的代码显然对数据类型的大小做出了许多不安全的假设,而这恰好对 Win32 是正确的。如果您只想运行该程序,而不是对其进行持续维护,那么将其构建为 Win32 程序可能是您最简单、最安全的选择。 这是什么意思?您从 Clang 收到此消息。您是否使用 Clang 生成错误消息并使用单独的编译器生成对象模块? Mingw32 封装了一个 GCC 版本,GCC 非常擅长代码诊断,尤其是当您提高警告级别时(“-Wall -Wextra -pedantic”可能会产生比您真正想要的更多的警告)。依赖不同的编译器进行 linting 而不是编译似乎是愚蠢的,因为这样您就不能指望出现特定于实现的问题,并且您可能会遇到不同扩展集的问题。 对于任何有兴趣回答的人来说,这里的主要问题是我对 Clang 和 clangd 的混淆。通过将语言服务器设置为知道我的目标是 x86 机器,clangd(不是 Clang)不再给我警告。我错误地将其标记为 Clang 问题,但我只使用了在代码分析期间调用 Clang 的 clangd,它无法知道我的目标架构是什么。 【参考方案1】:

所以问题是(DWORD*)bb 的类型是int。这意味着代码需要重新设计,因为有人将指针塞入int。 Microsoft 为指针大小的整数制作了一种特殊类型:DWORD_PTR。是的,stdint.h 中肯定有一个,如果你愿意,你可以使用那个,但如果你已经在使用DWORD,你不妨使用DWORD_PTR。这条线没有出现问题。问题发生在 b 被指针赋值的那一行。

b 的类型更改为intptr_tuintptr_tDWORD_PTR,然后反向传播更改,直到错误消失。如果你到了你不能的地方,那部分代码就需要重新设计。

即使在 32 位编译中,当类型不是整数指针类型之一时,Microsoft 自己的编译器现在也会对这些东西产生警告。最好是警告。

在整数中填充指针不再是推荐的做法,但 Win32 API 无处不在,所以在罗马时...

【讨论】:

我建议您阅读我帖子中的评论链,尤其是我最近的评论,并相应地编辑您的答案,以便我接受。 @daedsidog:我已经读过了。我仍然建议将类型交换为整数指针类型之一。当您需要此代码以 64 位运行时,这一天可能会到来,即使不需要,对于下一个人来说,它也更容易阅读。 我在精神上同意,但我的双手被束缚了。就像你所说;在罗马的时候...

以上是关于C:在处理 32 位程序时,在 Windows 64 位机器上将 int 转换为 int* 时出现警告的主要内容,如果未能解决你的问题,请参考以下文章

Window 32位 编程总结

在 C 中将 32 位应用程序转换为 64 位应用程序

在 Windows 32 位中安装 Roracle 软件包时出错

检测32位或64位Windows

TestComplete 64位和32位之间的区别

在 Windows 7 [32 位] 中启动 MongoDB 时出错