跨平台:选择使用32/64位的数据类型

我正在试验我的第一个需要在Linux Redhat 5.3和Windows XP / Vista / 7上运行的跨平台应用程序。

由于某些操作系统将运行x86或64,我想知道要声明的数据类型。

我不想使用任何库来实现跨平台的可移植性; 我想先自己做实验。

如果我需要一个int,我应该声明int32或int64还是只是int?

如果我要在64位操作系统上编译并使用int32那么数据会被截断为32位值,所以我会丢失一些数据吗?

我想知道如果我在具有不同架构的不同操作系统上运行我应该如何声明。

在许多64位操作系统(例如64位Linux)中,整数仍然只有32位宽; 只有long和指针是64位宽。 这被称为LP64数据模型 。 原因在于,在许多情况下,int不需要比32位提供的范围更多的范围,并且使用64位只会浪费内存。 在64位Windows下,evens longs是32位(与32位Windows的兼容性),只有long long是64位; 这被称为LLP64数据模型。

如果您的应用程序将在32位和64位操作系统上运行,那么32位整数的范围显然已足够 – 否则,您将在32位操作系统上遇到麻烦。 因此,在这些情况下,请继续使用整数。 如果您可以识别需要64位整数范围的情况,请显式使用int64_t (在stdint.h定义)。 要确保您写入磁盘的二进制数据格式在不同平台上兼容,请在这些位置明确使用int32_tint64_t ……但也要注意潜在的字节序问题。

最后,在编写64位代码时,请注意指针无法在LP64数据模型中转换为int – 因此请使用uintptr_t

如果您编写干净的代码,32位/ 64位可移植性应该几乎不是问题 – 除了上面所写的内容之外,您还不需要了解更多内容。 Windows和Linux之间的可移植性将产生更大的问题,即32位和64位之间的可移植性。

如果需要整数,请键入int ,依此类推。 如果您需要假设数据类型可以容纳什么(例如,您需要它有32位),请查看stdint.h

只要您确保不假设数据类型可以容纳什么,您就会处于良好状态。 当你做一些假设一个数据类型的东西将持有n位时,你就会进入实现定义的土地,你需要确保它在两个平台上都有效。

在大多数情况下,您不需要固定尺寸 – 您只需要最小尺寸。 普通的旧C数据类型确实具有这样的最小尺寸(范围):

 type | minimum size -------------------+--------------------------------------------- char | at least 8 bits (but see below) signed char | -127 to 127 unsigned char | 0 to 255 short | -32767 to 32767 unsigned short | 0 to 65536 int | -32767 to 32767 unsigned int | 0 to 65536 long | -2147483647 to 2147483647 unsigned long | 0 to 4294967295 long long | -9223372036854775807 to 9223372036854775807 (see below) unsigned long long | 0 to 18446744073709551615 (see below) 

char必须与signed charunsigned char具有相同的范围unsigned char long longunsigned long long是C99规范的新增内容,但在许多只支持旧标准的编译器中作为扩展存在)。

使用大到足以适合您感兴趣的值范围的大小,加上size_t用于对象大小/对象数/数组索引,在大多数情况下你都是正确的。

的其他类型值可能很有用,但应谨慎使用。

您需要使用适合您正在处理的数据的数据类型,并且您希望确保不会跨平台更改使用来自stdint.h的uint32_t,uint16_t等

最重要的是,如果您正在操作其大小随底层架构(例如容器大小)而变化的值,则应使用size_t,因为它将适应编译器目标,例如32或64位。