奔向64位② 新平台下的数据类型
软件世界
这一篇中我们将探讨一些比较基本的、语言层面的问题:在64位下,C/C++还是原来的C/C++吗?很快我们就会发现:是的,C/C++大体上还是原来的C/C++,语法系统是不会变的,你所熟悉的一切在新的环境中仍然是合用的。不过,新的64位环境的引入,也或多或少地给C/C++带来一些新的变化。这些变化主要影响的是数据表示──在新环境中,可以在一个时钟周期内传送更大的整数,当然没有理由白白地浪费总线的数据宽度。所以,一些新的非标准数据类型被引入,用来完成在新环境中更有效的数据表示的任务。
内存尺寸
先来看一看原有的东西现在成了什么样子。首先应该明确的是:被用作malloc()和new的内存尺寸参数类型size_t在新环境中是必然要改变的:它永远代表的是计算机的字长。无论在什么计算机上,我们总是可以用sizeof size_t来取得字长,当然在64位环境中,这个表达式的值是8。如果在程序语义上,你的代码中就是以size_t来表示基本“计算机字长”的,那这个代码将是可移植的。还有int呢?它也变成了64位吗?并没有,它仍然是32位的。这样做是为了和大多数的非Windows操作系统兼容,毕竟C/C++带有浓厚的UNIX环境背景。但对于long来说,究竟尺寸是多少,这并不知道,可能是32位也可能是64位。关于这一点,我们是没有办法从产品的Beta版中看到的。而C/C++语言标准也仅仅规定了sizeof char≤sizeof int≤sizeof long,所以究竟是多少,你应该在动手编程之前手工做一下测试,并且不要对long的尺寸作任何假定,更不要把程序的主要逻辑建立在这种假定上。
接下来,看看还有什么新东西。__int64在一些环境中被引入,以表示明确的64位整数,这些环境中,long和int都还是32位。这些数据类型是原生的(primitive)数据类型,倾向于不可移植。我们需要记住的一点是:永远别在自己的代码里使用或调用以下划线开头的标识符,除非你在编写以后不可见的代码,例如库。
新的指针
另一个比较重要的问题是指针。在64位环境中,指针的尺寸是多少呢?我们可以合理地预期到,指针的尺寸被加倍了。因为指针的值是内存地址,而在64位环境下,有大得多的内存地址范围需要表示。所以,指针的尺寸必然被加倍了。这一点,我们可以通过表达式sizeof void*的值来验证。
Windows API并非语言层面的库,但在Windows程序设计中,它还是比较重要的。读过一些书或代码的读者知道,在API里有一种比较通用的数据类型称为DWORD,它的尺寸是32位。在新的环境中,如果将原生类型size_t的值赋给DWORD,将会发生截断(truncation)。为此Windows API引入了10种新的数据类型来表示不同尺寸的整数,并区分了有符号数和无符号数,它还引入了11种新的指针类型来在字面上(literal)规定了指针语义尺寸,这些类型在windows.h中定义,LPARAM和WPARAM在wtypes.h中定义。这些类型的尺寸只是语义尺寸。在Windows环境中,我们可以指望它们的可移植性,因而这种类型一般称为多态(polymorphic)。
小结
现在我们已经看到有这么多的数据类型,如何在程序设计中高效地使用它们?首要的就是要了解它们!常到头文件中看看结构和类声明,尽可能地使自己适应Windows的新数据类型。当然,这一切在汇编层都是完全相同的,编译器总会尽量把结构体的类型作合适的捆扎。因此,在编写高级应用时,数据类型的考量应该少些──为什么要替聪明的编译器操心呢?当然了,你可以用/WP64开关让编译器警告你:现在已经在64位环境下了,一切都要当心!
预告:下期将为大家介绍64位平台下的内存管理。