随着64位体系结构的普及,针对64位系统准备好您的Linux?软件己经变 得比以前更为重要。在本文中,您将学习如何在进行语句声明、赋值、位移、类 型转换、字符串格式化以及更多操作时,防止出现可移植性缺陷。
Linux是可以使用64位处理器的跨平台操作系统之一,现在64位的系统在服 务器和桌面端都已经非常常见了。很多开发人员现在都面临着需要将口己的应用 程序从32位环境移植到64位环境中。随着Intel? Itanium?和其他64位 处理器的引入,使软件针对64位环境做好准备变得日益重耍了。
与UNIX?和其他类UNIX操作系统一样,Linux使用了 LP64标准,其中指 针和长整数都是64位的,而普通的整数则依然是32位的。尽管有些高级语 言并不会受到这种类型大小不同的影响,但是另外一些语言(例如C语言)却 的确会受到这种影响。
将应用程序从32位系统移植到64位系统上的工作可能会非常简单,也可能 会非常困难,这取决于这些应用程序是如何编写和维护的。很多琐碎的问题都可 能导致产生问题,即使在一个编写得非常好的高度可移植的应用程序屮也是如 此,因此本文将对这些问题进行归纳总结,并给出解决这些问题的一些方法建议。
64位的优点
32位平台有很多限制,这些限制正在阻碍大型应用程序(例如数据库)开发人 员的工作进展,尤其对那些希望充分利用计算机硬件优点的开发人员來说更是如 此。科学计算通常要依赖于浮点计算,而冇些应用程序(例如金融计算)则需要 一个比较狭窄的数字范围,但是却要求更高的精度,其精度高于浮点数所提供的 精度。64位数学运算提供了这种更高精度的定点数学计算,同时还提供了足够 的数字范围。现在在计算机业界屮冇很多关于32位地址空间所表示的地址空间 的讨论。32位指针只能寻址4GB的虚拟地址空间。我们可以克服这种限制, 但是应用程序开发就变得非常复杂了,其性能也会显著降低。
在语言实现方面,目前的C语言标准要求“long long”数据类型至少是64位 的。然而,其实现可能会将其定义为更大。
另外一个需要改进的地方是口期。在Linux中,□期是使用32位整数来表示 的,该值所表示的是从1970年1月1 EI至今所经过的秒数。这在2038年
就会失效。但是在64位的系统中,H期是使用有符号的64位整数表示的, 这可以极大地扩充其可用范围。
总之,64位具有以下优点:
64位的应用程序可以直接访问4EB的虚拟内存,Intel Itanium处理器提 供了连续的线性地址空间。
64位的Linux允许文件大小最大达到4 EB (2的63次慕),其重要 的优点之一就是可以处理对大型数据库的访问。
Linux 64位体系结构
不幸的是,C编程语言并没有提供一种机制来添加新的基本数据类型。因此, 提供64位的寻址和整数运算能力必须要修改现冇数据类型的绑怎或映射,或者 向C语言中添加新的数据类型。
表1.32位和64位数据模型
ILP32
LP64
LLP64
ILP64
char
8
8
8
8
short
16
16
16
16
int
32
32
32
64
long
32
64
32
64
long long
64
64
64
64
指针
32
64
64
64
这3个64位模型(LP64、LLP64和ILP64)之间的区别在于非浮点数据类 型。当一个或多个C数据类型的宽度从一种模型变换成另外一种模型时,应用 程序可能会受到很多方面的影响。这些影响主要可以分为两类:
?数据对象的大小。编译器按照自然边界対数据类型进行対齐;换而言之, 32位的数据类型在64位系统上要按照32位边界进行対齐,而64位 的数据类型在64位系统上则要按照64位边界进行对齐。这意味着诸如 结构或联合之类的数据对象的大小在32位和64位系统上是不同的。
?基本数据类型的大小。通常关于基本数据类型之间关系的假设在64位 数据模型上都已经无效了。依赖于这些关系的应用程序在64位平台上编 译也会失败。例如,sizeof (int) = sizeof (long) = sizeof (pointer)的假 设对于ILP32数据模型有效,但是对于其他数据模型就无效了。
总Z,编译器要按照自然边界对数据类型进行对齐,这意味着编译器会进行’‘填 充”,从而强制进行这种方式的对齐,就像是在C结构和联合中所做的一样。结 构或联合的成员是根据最宽的成员进行对齐的。清单1对这个结构进行了解 释。
清单1.C结构
struct test {
int il;
double d;
int i2;
long 1;
表2给岀了这个结构中每个成员的大小,以及这个结构在32位系统和64位 系统上的大小。
表2?结构和结构成员的大小
在64位系统上的大小32位结构成员
在64位系统上的大小
32位