不久前,有人告诉我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以上的项目。

在Cygwin中,sizeof(long)== 8,即使在Windows上也是如此:-)

@SergeRogatch他们应该使用size_t或迭代器类型进行迭代,而不是int或int64_t

@LưuVĩnhPhúc,使用size_t,它在接近负数时变得棘手,因为size_t是无符号的。因此for(size_t i = 0; i = 0; i -)。

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

#1 楼

在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中的LP(也就是说,根据Aspen组的建议,几乎所有后来的参与者都使用LP64;只有具有64位操作悠久历史的系统才使用其他方案)。所有现代的64位Unix系统都使用LP64。 MacOS X和Linux都是现代的64位系统。Microsoft使用不同的方案过渡到64位:LLP64(“ long long,指针是64位”)。这具有意味着无需更改即可重新编译32位软件的优点。它有与众不同的缺点,并且还要求修改代码以利用64位容量。总是有必要进行修订;这是与Unix平台所需的修订版本不同的修订集。在平台上可用,以有符号(列出)和无符号(未列出;前缀为'u')提供:



<inttypes.h>-8位整数

int8_t-16位整数

int16_t-32位整数

int32_t-64位整数
int64_t-无符号足以容纳指针的整数

uintptr_t-平台上整数的最大大小(可能大于intmax_t

然后,您可以在需要的地方使用这些类型对应用程序进行编码,并在使用系统类型时要非常小心(可能有所不同)。有一个int64_t类型-用于保存指针的带符号整数类型;您应该计划不使用它,或仅将其减去两个intptr_t值(uintptr_t)来使用它。用于64位计算机上整数数据类型的大小。习惯它;世界不会改变。

评论


对于使用时间已经足够长的用户来说,64位转换与80年代中期的16位到32位转换有些相似。有些计算机是IL32,而其他计算机则是L32(使新的符号适应旧的问题)。有时'int'是16位,有时是32位。

–乔纳森·莱弗勒(Jonathan Leffler)
08-12-22在16:39

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

–Jörg W Mittag
08/12/23在17:46

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

–乔纳森·莱弗勒(Jonathan Leffler)
08年12月24日在7:05

@TomFobear:ILP64存在一个主要问题-您如何称呼32位类型?或者,如果您将32位类型称为short,那么您将其称为16位类型呢?并且,如果您将16位类型的char称为UTF-16等,那么您将其称为8位类型呢?因此,使用LP64将使您拥有8位字符,16位短字符,32位int,64位长,并且在相关时(如果?)可以向上扩展到128位长。在那之后,您获得的256的幂比您在C中拥有的名字更多(好吧,我想您可以拥有256位的intmax_t,然后才用完)。 LP64有其优点。

–乔纳森·莱弗勒(Jonathan Leffler)
2012年2月15日在16:39

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

– Compholio
13年2月21日在14:17

#2 楼

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

Windows数据类型

该信息在各种Windows头文件(例如INT)中也可用。我在这里列出了一些相关的类型:

Type                        | S/U | x86    | x64
----------------------------+-----+--------+-------
BYTE, BOOLEAN               | U   | 8 bit  | 8 bit
----------------------------+-----+--------+-------
SHORT                       | S   | 16 bit | 16 bit
USHORT, WORD                | U   | 16 bit | 16 bit
----------------------------+-----+--------+-------
INT, LONG                   | S   | 32 bit | 32 bit
UINT, ULONG, DWORD          | U   | 32 bit | 32 bit
----------------------------+-----+--------+-------
INT_PTR, LONG_PTR, LPARAM   | S   | 32 bit | 64 bit
UINT_PTR, ULONG_PTR, WPARAM | U   | 32 bit | 64 bit
----------------------------+-----+--------+-------
LONGLONG                    | S   | 64 bit | 64 bit
ULONGLONG, QWORD            | U   | 64 bit | 64 bit


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

#3 楼

MSDN上的这篇文章引用了一些类型别名(在Windows上可用),这些别名在宽度方面更加明确:
/aa505945.aspx

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

评论


是否可以保证uint32_t和DWORD可以互换?不难想象它们可能不是[例如如果前者是32位整数,而后者是32位长,则gcc将假定指向一种类型的指针将尽管它们的表示形式匹配也无法为另一种类型别名。

–超级猫
16年5月18日在21:53

#4 楼

Microsoft还为与指针大小相同的整数定义了UINT_PTR和INT_PTR。这里是Microsoft特定类型的列表-这是其驱动程序参考的一部分,但我认为它对常规编程有效也是。

#5 楼

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

#include <iostream>

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


乘以8是从字节中获取位。如果您需要特定的大小,则通常最容易使用库的预定义类型之一。如果不希望这样做,您可以使用autoconf软件执行常见的操作,并让配置系统确定所需大小的正确类型。

评论


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

–安德烈斯
09-10-16在19:26

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

– Paul de Vrieze
09-10-25在20:08

但是OP并没有询问他的编译器/平台。他特别询问了有关64位Windows的问题—大概是因为他不方便访问要进行测试的64位Windows系统。

– Quuxplusone
2013年12月2日23:09

#6 楼

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

可以使用sizeof(long)进行检查。

#7 楼

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