我目前正致力于将32位应用程序转换为C语言中的64位应用程序。此应用程序目前正在开发x86架构(Windows,osx,Unix,Linux)。因此,在开始编码之前,我想知道在转换应用程序时我需要考虑什么。
答案 0 :(得分:26)
LONG
不是long
。(int)&x
演员阵容并使用intptr_t
和(unsigned int)&x
键入uintptr_t
char*
以对其进行指针运算的内容。4 = sizeof(void*)
#ifdef RUN64
或类似内容。如果128位平台变得流行,你会后悔的。 EDIT 根据评论的建议添加了uintptr_t
条。
答案 1 :(得分:8)
一个尚未提及的潜在问题是,如果您的应用从磁盘读取或写入二进制数据(例如,使用fread
读取结构数组),您将需要非常仔细地检查并且可能结束有两个读者:一个用于遗留文件,一个用于64位文件。或者,如果您谨慎使用uint32_t
头文件中的<stdint.h>
等类型,则可以重新定义结构以进行逐位兼容。无论如何,二进制I / O 是需要注意的事项。
答案 2 :(得分:5)
这实际上取决于应用程序及其编码方式。有些代码可以用64位编译器重新编译,它只会工作,但通常只有在代码设计时考虑到可移植性时才会发生这种情况。
如果代码对本机类型和指针的大小有很多假设,如果它有很多位打包或使用字节指定的协议与外部进程对话,但使用一些关于大小的假设本机类型然后可能需要一些或大量的工作才能获得干净的编译。
几乎每个演员和编译器警告都是需要签出的红旗。如果代码不是“警告干净”,那么这也表明可能需要做很多工作。
答案 3 :(得分:4)
如果您为您的值使用了正确的类型 - 例如。 size_t
,ptrdiff_t
,uintptr_t
,stdint.h
中适当的固定大小的int类型 - 并且没有硬编码值大小,您的代码应该开箱即用。
答案 4 :(得分:3)
切换到64位时遇到的主要问题是指针的大小不同(64位而不是32位)整数的大小和长度的大小也可能不同,具体取决于平台。
为什么这是一个问题?好吧,它不是,除非你的代码假定sizeof(int)== sizeof(void *)。这可能会导致令人讨厌的指针错误。
答案 5 :(得分:3)
嗯,从根本上说,变化的数量相当小,但如果不仔细编写应用程序,那么它仍然是一项重大任务。
主要区别在于指针是64位宽,但是大多数其他数据类型都没有改变。 int仍然是32位,而long可能仍然是32位。因此,如果你的代码在int和指针之间进行转换,那就会破坏。类似地,依赖于成员的特定偏移量的任何结构或类似物可能会破坏,因为其他成员现在可能更大,因此更改偏移量。
当然,你的代码首先不应该依赖这些技巧,所以在一个理想的世界中,这根本不是问题,你可以简单地重新编译,一切都会起作用。但你可能不是生活在一个理想的世界......;)
答案 6 :(得分:2)
C中32位和64位编程的两个主要区别是sizeof(void *)和sizeof(long)。您将遇到的主要问题是大多数Unix系统使用I32LP64标准,该标准定义了长达64位,而Win64使用IL32LLP64标准,该标准定义了长达32位。如果需要支持跨平台编译,则可能需要为32位和64位整数使用一组基于体系结构的typedef,以确保所有代码的行为一致。作为C99标准的一部分,它作为stdint.h的一部分提供。如果您不使用C99编译器,则可能需要滚动自己的等效项
如其他地方所述,转换的主要问题是假设sizeof(int)== sizeof(long)== sizeof(void *)的代码,支持已写入磁盘的数据的代码和跨平台IPC的代码
要详细了解背后的历史,请查看ACM Queue中的article。
答案 7 :(得分:2)
已经有很多好的答案。
考虑使用Gimpel Lint。它可以准确地指出有问题的构造类型。如果您的体验与我的一样,它也会向您显示与32/64位端口无关的系统中的大量错误。
答案 8 :(得分:2)