2 “32-bit”与“64-bit”的问题
2.1 “32-bit”与“64-bit”的兼容性问题
“32-bit”的应用程序需要得到操作系统、编译器、链接库等的支持才能在特定目标平台上运行。通常的关系可以参看下表:
表2 编译器和操作系统关系
| 32-bit操作系统 | 64-bit操作系统 |
32-bit编译器 | 可编译程序 | 可编译程序 |
64-bit编译器 | - | 可编译程序 |
表3 编译后的应用程序和操作系统关系
| 32-bit操作系统 | 64-bit操作系统 |
32-bit应用程序 | 可运行 | 可运行(依赖于特定环境),但不能有效发挥机器性能 |
64-bit应用程序 | - | 可运行,有可能有效发挥机器性能(取决于能否利用大内存等) |
2.2 “32-bit”到“64-bit”的移植问题
目前64位机器的使用越来越多,并将逐步替换32位的机器。为了移植“32-bit”的应用到“64-bit”下,通常需要考虑如下一些问题:
1) 数值类型表示的任何对象的取值范围
2) 指针的寻址范围
如下以Visual C++创建在64位Windows操作系统中运行的应用程序为例,看看移植时需要考虑的问题[1]。
1) 在64位Windows操作系统中,int和long是32 位值。如要编译为 64 位平台的程序,注意不要将指针赋给32位变量。
2) 在64位平台上,指针为64位,如果将该指针赋给32位变量,则应截断该指针值。
3) 在64位Windows操作系统中,size_t、time_t 和 ptrdiff_t 是 64 位值。
4) 在32位Windows操作系统上Visual C++ 2005之前的Visual C++ 版本中,time_t是32 位值。在Visual C++ 2005和更高版本中,默认情况下,time_t是64 位整数。应注意代码在哪里采用 int 值并将其作为 size_t 或 time_t 值处理。数字有可能增长得比 32 位数大,并且数据在被传递回int存储时有可能被截断。
5) %x(十六进制 int 格式)printf 修饰符在 64 位 Windows 操作系统中不会按预期的那样工作。它只对传递给它的值的前 32 位值执行操作。
6) Windows 32位操作系统使用%I32x显示整数。
7) Windows 64位操作系统使用%I64x显示整数。
所以,具体而言,需要考虑的就是同“范围”有关的内容。比如,数据库系统如果自己管理内存,那么通常使用共享缓冲,在移植时,就需要考虑共享缓冲的大小问题。以前受限于“32-bit”,最大内存理论上不得大于4G,但是在移植到“64-bit”后,这个限制被突破了,这就需要我们在定义共享内存的时候,考虑使用具有更大数值范围的数据类型来表示共享内存的地址信息。比如,在PostgreSQL7.4中,CreateSharedMemoryAndSemaphores函数中表示共享缓冲大小的类型用的是“int”,而在PostgreSQL8.3中,同样的函数中,表示共享缓冲大小的类型用的就变为“size_t”,size_t是标准C定义的数据类型,在32位机器中,size_t定义为 unsigned int,为4个字节,最多寻址4G的空间;在64位机器中,size_t定义为64位,最大寻址16EB字节的空间。