我注意到int和long的大小相同。为什么?

7

我在OSX上注意到了这一点,觉得很奇怪,因为我期望long比int更大。 是什么原因使它们的大小相同呢?

5个回答

14

这是C和C ++语言规范中大小定义宽松性的结果。我相信C具有特定的最小大小,但在C ++中唯一的规则是:

1 == sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long)

此外,sizeof(int)sizeof(long) 在所有平台上的大小都不相同。在我使用过的每个64位平台上,long 都适合自然字长,因此在32位体系结构上为32位,在64位体系结构上为64位。


3
据我所知,Windows 64位是一个例外。它采用LLP64模型,因此long=32位,而long long=64位。这取决于你作为实现者认为什么更重要,是保持sizeof(long)=sizeof(pointer),还是拯救假设sizeof(long)=sizeof(int)的代码。微软选择了后者。 - Marco van de Voort
Marco van de Voort提出了一个很好的观点。回到过去,在16位机器上,int通常与short大小相同,而long是新的、大的32位大小。因此,从足够大的角度来看,关于int与哪个大小相同没有固定的规则——我相信有一些机器具有16位short、32位int和64位long值,尽管它们并不是非常流行,因为大多数代码假定(sizeof int == sizeof short || sizeof int == sizeof long) && sizeof short != sizeof long。 - Jonathan Leffler

8
  • int是最方便和高效的整数类型。
  • long是/曾经是最大的整数类型。
  • short是最小的整数类型。

如果最长的整数类型也是最有效的,那么int就与long相同。在一段时间前(考虑到32位之前),由于16位是最宽的自然整数,因此在许多平台上sizeof(int) == sizeof(short)


1
char是一种整数类型,通常比short更小。 - Bastien Léonard
char类型有点奇怪...它本身具有实现定义的符号,因此它是一种奇怪的整数类型。考虑 "char c = -1; int i = c; unsigned u = c;"。i和u的值是实现定义的。我同意"unsigned char"和"signed char"都是整数类型 ;) - D.Shawley
在64位系统上,long仍然是32位的,因此它不是最大的整数类型,就像short也不是最小的。 :) - jalf
根据标准,bool是最小的整数类型(3.9.1:7);-) - Steve Jessop
同意,我的意思是指范围最小,而不是存储最小。除非计算空基类优化,否则没有任何对象可以比 char 的存储更小。 - Steve Jessop
显示剩余2条评论

3

正如Tom所指出的那样,C++中唯一的标准大小是char,其大小为1(*)。从此开始,类型之间只有'不小于'的关系。大多数人会声称它取决于架构,但这更多是编译器/操作系统的决定。在运行MacOSX、Windows(32/64位)或Linux(32/64位)的相同硬件上,相同数据类型的大小将不同。在相同架构和操作系统中,不同的编译器可能具有不同的大小。即使在相同的硬件、操作系统和编译器下,根据编译标志,大小也可能不同:

$ cat test.cpp
#include <iostream>
int main()
{
   std::cout << "sizeof(int): " << sizeof(int) << std::endl;
   std::cout << "sizeof(long): " << sizeof(long) << std::endl;
}
$ g++ -o test32 test.cpp; ./test32
sizeof(int): 4
sizeof(long): 4
$ g++ -o test64 test.cpp -m64; ./test64
sizeof(int): 4
sizeof(long): 8

这是在MacOSX Leopard上使用gcc编译器的结果。可以看到,硬件和软件都相同,但两个可执行文件的大小确实不同,尽管它们是由相同的代码生成的。
如果您的代码依赖于大小,则最好不要使用默认类型,而是为编译器使用特定类型,使大小明确。或者使用一些提供支持的可移植库,例如ACE:ACE_UINT64将是一个64位无符号整数类型,无论编译器/操作系统/架构如何。该库将检测编译器和环境,并在每个平台上使用适当的数据类型。
(*) 我已重新检查了C ++标准3.9.1:char大小应足以存储任何实现基本字符集的成员。稍后在5.3.3中:sizeof(char),sizeof(signed char)和sizeof(unsigned char)为1,因此是的,char的大小为1字节。
阅读其他答案后,我发现有一个声明bool是最小的整数类型。同样,标准在要求方面很松散,仅说明它可以表示 true 和 false ,但不指定其大小。标准明确到这种程度:5.3.3,脚注:“sizeof(bool)不需要为1”。
请注意,一些C ++实现已决定出于其他原因使用大于1字节的布尔值。在Apple MacOSX PPC系统中,使用gcc,sizeof(bool)==4

1
sizeof(char)始终为1。但是,sizeof返回的结果是字符数(而不是八位字节)。CHAR_BIT可以是32等。 - Logan Capaldo
根据5.3.3节:“sizeof运算符产生其操作数对象表示所占的字节数。” - David Rodríguez - dribeas
1
请注意,就C或C++标准而言,“字节”不一定是八位组。这就是为什么有一个CHAR_BIT宏来给出字节中实际的位数(保证至少为8位)。 - bdonlan

3

int应该是体系结构的自然字长。在早期,像原始IBM PC这样的16位机器上,int是16位,long是32位。在像68000系列这样的32位机器上,int仍然是“自然字长”,现在是32位,而long保持在32位。随着时间的推移,long变为64位,然后我们开始使用像Intel Core 2这样的64位体系结构,所以我预计int迟早会增长到64位。

有趣的事实:在我的笔记本电脑上,使用Core 2 Duo和Mac OS X 10.5,int和long都是32位。在我的Linux桌面上,也使用Core 2 Duo和Ubuntu,int是32位,而long是64位。

多年前,在一次工作面试中,有人问我将3添加到int指针后,它会在哪里。我回答:“比现在大3倍sizeof(int)”。面试官追问我,我说这将取决于体系结构,因为(当时)Windows使用16位int,但由于我正在进行Unix编程,我更习惯于32位int。我没得到那份工作 - 我猜测面试官不喜欢我知道的比他多。


1
我认为在core2上int不是64位的。我认为只是long变长了。至少在64位Debian上,这是我的经验。 - Tom
你说得对,Tom,在我的MacBookPro上,int和long都是4个字节。 - Paul Tomblin
1
不是硬件而是编译器选择。完全相同的硬件在不同的操作系统和编译器下可能具有不同的 int 和 long 大小。在macosx上,针对intel core 2 duo的GCC编译器默认生成32位int/long。使用-m64选项将生成32位int和64位long(以及指针)。 - David Rodríguez - dribeas
没错,dribeas。在Paul的Ubuntu电脑上,gcc很可能是默认编译为-m64,而在OSX电脑上则是-m32。 - Tom

1

intlong的大小并不总是相同的,因此在代码中不要假设它们相同。历史上有8位和16位,以及更为常见的32位和64位架构。对于嵌入式系统来说,较小的字长仍然很常见。搜索网络以获取有关ILP32和LP64的过多信息。


而 LLP64,是 win64 所使用的方案。 - Marco van de Voort

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接