将 32 位移植到 64 位时处理问题的正确方法。从 DT1 转换为更大尺寸的 DT2

发布于 2024-09-04 17:40:10 字数 355 浏览 4 评论 0原文

所以我正在尝试将 32 位移植到 64 位。

我已经打开 VS2008 标志来检测 64 位的问题。

我正在尝试以下操作:

char * pList = (char *)uiTmp);

warning C4312: 'typecast' : conversion from 'unsigned int' to 'char *' of upper size

忽略代码本身。对于任何指针也是如此,因为 64 位指针大于 32 位 unsigned int 或 int。

考虑到您必须将较小的类型转换为较大的类型,您将如何做才能在 32/64 位系统上正确地执行此操作

So I am trying to port 32 bit to 64 bit.

I have turned on the VS2008 flag for detecting problems with 64 bit.

I am trying following:

char * pList = (char *)uiTmp);

warning C4312: 'type cast' : conversion from 'unsigned int' to 'char *' of greater size

Disregard the code itself. This is also true for any pointer, because 64 bit pointer is greater than 32 bit unsigned int or int for that purpose.

Given that you have to cast smaller type to greater how would you go about doing it so it correctly on both 32/64 bit systems

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

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

发布评论

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

评论(4

长安忆 2024-09-11 17:40:11

Basetsd.h 标头具有 用于在指针和整数之间转换的各种函数。特别是,函数 UIntToPtr 可能就是您想要的:

char * pList = UIntToPtr(uiTmp);

这将对给定的 unsigned int 值进行零扩展,即在 64 位版本中,pList 指针的高 32 位将为零。

The Basetsd.h header features various functions for converting between pointers and integers. In particular, the function UIntToPtr might be what you want:

char * pList = UIntToPtr(uiTmp);

This will zero-extend the given unsigned int value, i.e. in 64bit builds, the upper 32bit of the pList pointer will be zero.

人海汹涌 2024-09-11 17:40:11

从 32 位平台迁移到 64 位平台时需要注意的要点:

  • 不再是 sizeof(int) != sizeof(void*)。审核所有将整数强制转换为指针并返回的情况。
  • 结构对齐和尺寸发生变化。例如,以下内容在 32 位上打包为 8 个字节,但中间有一个洞,在 64 位上占用 16 个字节:
    struct list
    {
        int          val_;
        struct list* next_;
    };
  • IPC 和网络通信的隐式假设会让您感到困扰。

我多次遇到的一个具体问题是,在 32 位 Linux 上重复调用 vprintf (3)无需重新初始化va_listva_end/va_start 默默地工作(虽然是未定义的行为),但由于不同的调用约定,在 64 位上会大声轰炸。

Main points to watch out for when moving from 32 to 64 bit platform:

  • sizeof(int) != sizeof(void*) anymore. Audit all occurrences of casting integer to pointer and back.
  • Structure alignment and sizes change. For example the following is packed into 8 bytes on 32 bit, but has a hole in the middle and takes 16 bytes on 64 bit:
    struct list
    {
        int          val_;
        struct list* next_;
    };
  • Implicit assumptions for IPC and network communications will bite you.

One specific issue I came across several times was that on 32-bit Linux repeated calls to vprintf(3) without re-initializing va_list with va_end/va_start silently works (while being undefined behavior), but loudly bombs on 64-bit due to different calling convention.

妥活 2024-09-11 17:40:10

这不是一个可以忽略的警告,它会在 64 位代码中崩溃。无符号整型不能存储指针。没有任何魔法可以让这项工作成功。

检查您的代码并重新考虑将指针值存储在无符号整数中。它可能应该是一个空*。如果您#include,则可以使用 UINT_PTR。

This is not a warning you can ignore, it will bomb in 64-bit code. An unsigned int cannot store a pointer. There's no magic cast that will make this work.

Review your code and rethink storing pointer values in an unsigned int. It should probably be a void*. If you #include <windows.h> then you can use UINT_PTR.

梨涡 2024-09-11 17:40:10

我也有同样的问题。在我的例子中,代码试图使用 rand() 生成一个随机句柄,它返回一个 32 位值。 (为什么它需要一个随机句柄值?不要问...)

我发现可以安抚编译器的方法如下:

char * pList = (char *)(0) + uiTmp; 

如果您的系统使用 32 位或 64 位,这应该可以正常工作位指针。当然,您可能不想在 64 位平台上使用 32 位整数,具体取决于您的代码到底在做什么。

I had the same problem. In my case the code was trying to generate a random HANDLE using rand() which returns a 32-bit value. (Why did it want a random handle value? Don't ask...)

What I found works to appease the compiler was the following:

char * pList = (char *)(0) + uiTmp; 

This should work OK if your system uses 32-bit or 64-bit pointers. Of course you might not want to be using 32-bit integers on a 64-bit platform, depending on what exactly your code is doing.

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