64位Windows上long的位大小是多少?


137

不久前,有人告诉我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上定义类似(uwsw((un)signed width))的东西,long否则是否要检查目标CPU的位大小?


在具有MSVC ++的Windows上,int和long是32位:msdn.microsoft.com/zh-cn/library/3b2e7499.aspx。但是,为了允许例如向量存储4G以上的项目,size_t为64位。因此,需要使用int64_t而不是int来迭代例如可能包含4G以上项的向量。
Serge Rogatch


@SergeRogatch他们应该使用size_t或迭代器类型来迭代,而不是intint64_t
phuclv

2
@LưuVĩnhPhúc size_t在负数附近变得棘手,因为它size_t是无符号的。因此for(size_t i=0; i<v.size()-2; i++)对于向量大小0和1失败for(size_t i=v.size()-1; i>=0; i--)
Serge Rogatch

2
如果您要对指针进行数学size_t运算(即使用值,则结果应保存在一个ptrdiff_t类型为变量的变量中-该变量应设计得足够大以容纳这样的结果,并且正是出于这种原因而为带符号的类型!)
SlySven

Answers:


260

在Unix世界中,对于64位平台的整数和指针的大小有一些可能的安排。两种最广泛使用的是ILP64(实际上只有很少的例子; Cray就是这样的例子)和LP64(几乎用于其他所有东西)。acronynms来自“ 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位计算机上的整数数据类型的大小,存在不同的系统。习惯它; 世界不会改变。


12
对于使用时间已足够长的用户,64位过渡与80年代中期的16位到32位过渡有些相似。有些计算机是IL32,而其他计算机则是L32(使新的符号适应旧的问题)。有时'int'是16位,有时是32位。
乔纳森·莱夫勒

4
不要忘记,这仅适用于C-ish语言。其他人则有更合理的规范,其中a)不允许编译器作者选择willi-nilly数据类型的大小,或者b)数据类型的物理表示形式不会“泄漏”,或者c)整数总是无限大。
约尔格W¯¯米塔格

2
是的-但是对于那些指定行为的语言,首先没有问题。例如,Java在所有平台上都有一个“长”号,但大小是固定的(64位?)。因此,移植到64位计算机没有任何问题。大小不变。
乔纳森·莱夫勒

17
@TomFobear:ILP64存在一个主要问题-您如何称呼32位类型?或者,如果您将其称为32位类型short,那么您将其称为16位类型吗?如果您将16位类型称为charUTF-16等,那么您将其称为8位类型是什么呢?因此,使用LP64将使您有8位char,16位short,32位int,64位的long空间,long long当(if?)变得相关时,还有向上扩展到128位的空间。在那之后,您拥有256的幂次幂,超过了用C语言命名的能力(嗯,我想您可以拥有256位intmax_t,然后才用完)。LP64有其优点。
乔纳森·莱夫勒

2
也许这对你们来说是显而易见的,但是我认为值得注意的是C#使用的整数大小与其他所有大小都不同。由于C#使用64位长(msdn.microsoft.com/en-us/library/ms173105.aspx),最近我绊倒了与DLL的接口。
Compholio

57

目前尚不清楚该问题是关于Microsoft C ++编译器还是Windows API。但是,没有[c ++]标记,因此我认为它与Windows API有关。一些答案因链接腐烂而受苦,因此我提供了另一个可能腐烂的链接。


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

Windows数据类型

各种Windows头文件(如)中也提供了该信息WinDef.h。我在这里列出了一些相关的类型:

类型 S / U | x86 | x64
---------------------------- + ----- + -------- + ------ --
BYTE,BOOLEAN | U | 8位| 8位
---------------------------- + ----- + -------- + ------ --
短裤 S | 16位| 16位
USHORT,WORD | U | 16位| 16位
---------------------------- + ----- + -------- + ------ --
INT,长| S | 32位| 32位
UINT,ULONG,DWORD | U | 32位| 32位
---------------------------- + ----- + -------- + ------ --
INT_PTR,LONG_PTR,LPARAM | S | 32位| 64位
UINT_PTR,ULONG_PTR,WPARAM | U | 32位| 64位
---------------------------- + ----- + -------- + ------ --
隆隆| S | 64位| 64位
ULONGLONG,QWORD | U | 64位| 64位

“ S / U”列表示已签名/未签名。


4

MSDN上的本文引用了许多类型别名(在Windows上可用),这些别名在宽度方面更为明确:

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

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


1
是否可以保证uint32_t和DWORD可以互换?不难想象它们可能不是(例如,如果前者是32位int,而后者是32位long,则gcc将假定指向一种类型的指针将尽管它们具有匹配的表示而不能为另一种类型别名)。
超级猫


2

在编译器/平台上了解它的最简单方法是:

#include <iostream>

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

8的乘法是从字节中获取位。

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


4
没关系,但是8位字节实际上不是C规范的一部分(C标准的3.6和5.2.4.2.1)。尽管很难找到不是8位的机器,但是您可以检查LONG_BIT以查看长数据类型的大小。
安德列斯(Andres)

当然,您是对的,它实际上取决于体系结构(“数据存储的可寻址单元足够大以容纳执行环境的基本字符集的任何成员”),但是最常用的体系结构等于8位。
Paul de Vrieze,2009年

但是OP并没有询问他的编译器/平台。他特地约64位Windows问-大概是因为他具备方便的访问到64位Windows系统的测试上。
Quuxplusone 2013年


-2

如果需要使用一定长度的整数,则可能应该使用一些平台无关的标头来帮助您。Boost是一个不错的地方。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.