150

不久前,有人告诉我,long在 64 位机器上不是 64 位,我应该始终使用int. 这对我来说没有意义。我看过文档(例如 Apple 官方网站上的文档)说long在为 64 位 CPU 编译时确实是 64 位。我在 64 位 Windows 上查找了它,发现

  • Windows:longint保持 32 位长度,并且为 64 位整数定义了特殊的新数据类型。

(来自http://www.intel.com/cd/ids/developer/asmo-na/eng/197664.htm?page=2

我应该使用什么?如果不在 Windows 上,我是否应该定义类似uw, sw((un)signed width) 的东西long,否则检查目标 CPU 位大小?

4

7 回答 7

277

在 Unix 世界中,对于 64 位平台的整数和指针的大小有几种可能的安排。最广泛使用的两个是 ILP64(实际上,只有极少数的例子;Cray 就是这样一个例子)和 LP64(几乎所有其他的例子)。首字母缩写词来自“int,long,指针是 64 位”和“long,指针是 64 位”。

Type           ILP64   LP64   LLP64
char              8      8       8
short            16     16      16
int              64     32      32
long             64     64      32
long long        64     64      64
pointer          64     64      64

ILP64 系统被放弃,取而代之的是LP64(也就是说,根据 Aspen 小组的建议,几乎所有后来的进入者都使用 LP64;只有具有 64 位操作传统的系统才使用不同的方案)。所有现代 64 位 Unix 系统都使用 LP64。MacOS X 和 Linux 都是现代 64 位系统。

Microsoft 使用不同的方案转换到 64 位:LLP64('long long,指针是 64 位')。这意味着 32 位软件可以在不改变的情况下重新编译。它的缺点是与其他人所做的不同,并且还需要修改代码以利用 64 位容量。总是需要修改;它只是一组与 Unix 平台所需的不同的修订。

如果您围绕平台中立的整数类型名称设计软件,可能使用 C99<inttypes.h>标头,当平台上可用类型时,该标头提供有符号(列出)和无符号(未列出;前缀为 'u'):

  • int8_t- 8 位整数
  • int16_t- 16 位整数
  • int32_t- 32 位整数
  • int64_t- 64 位整数
  • uintptr_t- 大到足以容纳指针的无符号整数
  • intmax_t- 平台上最大的整数大小(可能大于int64_t

然后,您可以在重要的地方使用这些类型对您的应用程序进行编码,并对系统类型(可能不同)非常小心。有一种intptr_t类型——一个有符号整数类型,用于保存指针;您应该计划不使用它,或者仅将其用作两个uintptr_t值相减的结果 ( ptrdiff_t)。

但是,正如问题所指出的那样(难以置信),64 位机器上整数数据类型的大小有不同的系统。习惯它; 世界不会改变。

于 2008-12-21T17:03:11.003 回答
61

目前尚不清楚问题是关于 Microsoft C++ 编译器还是 Windows API。但是,没有 [c++] 标签,所以我认为它是关于 Windows API 的。一些答案受到链接腐烂的影响,所以我提供了另一个可能腐烂的链接。


有关 Windows API 类型(如INT等)的信息LONG,MSDN 上有一个页面:

Windows 数据类型

该信息还可以在各种 Windows 头文件中获得,例如WinDef.h. 我在这里列出了一些相关的类型:

类型 | 南美 | x86 | x64
----------------------------+------+--------+------ -
字节,布尔值 | 你 | 8 位 | 8位
----------------------------+------+--------+------ -
简短 | 小号 | 16 位 | 16 位
USHORT,字 | 你 | 16 位 | 16 位
----------------------------+------+--------+------ -
INT,长 | 小号 | 32 位 | 32 位
UINT, ULONG, DWORD | 你 | 32 位 | 32 位
----------------------------+------+--------+------ -
INT_PTR、LONG_PTR、LPARAM | 小号 | 32 位 | 64 位
UINT_PTR、ULONG_PTR、WPARAM | 你 | 32 位 | 64 位
----------------------------+------+--------+------ -
龙龙 | 小号 | 64 位 | 64 位
乌龙龙,QWORD | 你 | 64 位 | 64 位

“S/U”列表示有符号/无符号。

于 2012-08-18T23:39:43.343 回答
4

MSDN 上的这篇文章引用了一些类型别名(在 Windows 上可用),它们的宽度更加明确:

http://msdn.microsoft.com/en-us/library/aa505945.aspx

例如,虽然您可以使用 ULONGLONG 来引用 64 位无符号整数值,但您也可以使用 UINT64。(对于 ULONG 和 UINT32 也是如此。)也许这些会更清楚一点?

于 2008-12-21T14:30:41.513 回答
4

Microsoft 还为与指针大小相同的整数定义了 UINT_PTR 和 INT_PTR。

这是Microsoft 特定类型的列表- 它是其驱动程序参考的一部分,但我相信它也适用于一般编程。

于 2008-12-21T16:01:15.373 回答
2

为您的编译器/平台了解它的最简单方法:

#include <iostream>

int main() {
  std::cout << sizeof(long)*8 << std::endl;
}

乘以 8 是从字节中获取位。

当您需要特定大小时,通常最容易使用一种预定义类型的库。如果不希望这样做,您可以执行 autoconf 软件经常发生的事情,并让配置系统确定所需大小的正确类型。

于 2008-12-21T15:01:22.997 回答
0

Windows 平台上的位大小long为 32 位(4 字节)。

您可以使用sizeof(long).

于 2020-01-22T04:58:47.387 回答
-3

如果您需要使用特定长度的整数,您可能应该使用一些独立于平台的标头来帮助您。Boost 是一个值得关注的好地方。

于 2008-12-21T14:13:19.317 回答