为什么C++中int和long类型都是4个字节?

21

许多来源(包括Microsoft)都将int和long类型都引用为4字节,并且范围为(有符号)-2,147,483,648至2,147,483,647。那么,如果long原始类型实际上没有提供更大的值范围,它的意义是什么呢?


即使由平台指定大小,定义它们相称的价值是什么? - hodgesmr
4
在你的实现中,int 占32位,而 long long 占64位。那么在两者之间选择多少位作为 long 的大小?在历史上,Windows 上的 long 大小一直保持在32位,因为在 Windows 上 int 的大小是16位。我模糊地怀疑 Windows 95 是第一个使用32位 int 的版本,但当时我还没有开始使用 C 进行编程,所以不确定。 - Steve Jessop
1
一个实现将所有整数类型都设为256位长,使它们的sizeof == 1是完全可以的。这也会证明std::vector<bool>是正确的! - Kerrek SB
@KerreSB:如果unsigned char的每个值都不能在int中表示,那么像getctolower这样的东西就会出现问题。这将无法区分EOF(int)UCHAR_MAX,或者对这些值调用字符函数。 - Steve Jessop
@SteveJessop 我更在想一般情况下单个八位字节的工作会有多麻烦。除此之外,我喜欢这个想法的新奇性。 - WhozCraig
显示剩余3条评论
8个回答

35

关于整数类型的唯一保证是:

  1. sizeof(char) == 1
  2. sizeof(char) <= sizeof(short)
  3. sizeof(short) <= sizeof(int)
  4. sizeof(int) <= sizeof(long)
  5. sizeof(long) <= sizeof(long long)
  6. sizeof(char) * CHAR_BIT >= 8
  7. sizeof(short) * CHAR_BIT >= 16
  8. sizeof(int) * CHAR_BIT >= 16
  9. sizeof(long) * CHAR_BIT >= 32
  10. sizeof(long long) * CHAR_BIT >= 64

其他方面取决于实现。由于(4),longint 可以具有相同的大小,但它必须至少为32位(感谢(9))。


2
略微偏离主题,但对于C++11,您可以添加 sizeof(long) <= sizeof(long long)sizeof(long long)*CHAR_BIT >= 64 - Mike Seymour
1
各种类型的大小范围并不是这些类型所保证的唯一内容。标准还保证了某些类型可以表示的最小和最大值。请参见此处获取更多信息。 - John Dibling
@JohnDibling,每种类型的最小大小隐含了最大和最小值 ((6) - (10))。 - Griwes
1
@JohnDibling,或者说大小由最小值和最大值隐含确定。这里就是这种情况;表示INT_MAXINT_MIN等需要至少32位。这仍然在答案中。 - Griwes
一个非二进制实现可能需要处理一些问题。尽管CHAR_BIT仅是“不是位域的最小对象的位数”,那么也许char并不需要具有CHAR_BIT位... - bames53
显示剩余8条评论

20

C++标准只规定long至少与int一样大,因此当其 恰好与int一样大的情况下没有任何问题:这完全取决于实现。在不同的平台上,大小可能会有所不同,例如我目前在我的Linux机器上有大小为4的int和大小为8的long


在Turbo C++中,int类型占用2个字节,而float类型占用4个字节。 - joey rohan

10

正如其他人指出的那样,该问题的假设只部分成立,即在某些平台上不成立。如果您真的想了解我们是如何走到当前的情况的,J. Mashey的《通往64位的漫漫长路》将为您展示存在的各种力量以及它们之间的相互作用。

简而言之,C语言最初有char(8位)和int(16位)。然后添加了short (16位)和long(32位),而int根据平台自然长度和向后兼容性的压力可能是16或32位。当64位出现时,添加了long long作为64位类型,并对64位平台上的较小类型进行了一些调整。随着32位int稳定下来,但long保持着各种定义,一些64位平台具有64位long,而其他平台(也许仅限于Windows?)将long保持为32位,可能是由于向后兼容性的不同压力(Unix有一个长期假设long与指针大小相同,Windows在其API中仍有更多的遗留物来自于int为16位时的时间,因此long是唯一的32位类型)。BTW typedefs(intXX_tintptr_t)被添加以帮助使意图更清晰,但intXX_t族可能会强制使用常数大小,但实际上并不需要。


谢谢。我讨厌那些只是机械地吐出标准答案的回复。每个人都知道这些。更重要的是,为什么标准会以这种方式存在,更重要的是,为什么主要的实现会以这种奇怪的方式进行操作。你的回答有助于理解这一点。 - Shital Shah

3
不,只有在某些平台上才是4个字节。C++标准将其大小留给实现定义。
在其他平台上,它的大小可能会不同。

@juanchopanza:已经指定了最小范围。根据实现中的CHAR_BIT,您可以推断出最小大小。 - Steve Jessop
@SteveJessop没错。我假装OP的问题纯粹以字节为单位,最小大小是固定的,但他们加入了一些最小和最大数字,这使问题有点混乱。 - juanchopanza

3
它不一定要更大。例如,当我在我的机器上使用GCC时,通常将long定义为8个字节。标准的措辞通常说这些类型“至少需要X大小”(例如,请查看C++11中最终规范化的long long)。
基本上,只要满足要求,任何人都可以自由地做他们想做的事情。根据标准,有人可以将long long设置为256位,并且它是完全合法的。

3
C++语言规范简单地说明了long类型的大小至少要与int相同。曾经标准的做法是让int占用2个字节,而long占用4个字节。由于某种原因,int变大了,而long保持不变(至少在Windows编译器中是这样)。我只能猜测long之所以保持不变,是为了向后兼容。请注意,本文中出现的HTML标签已被保留。

这个问题与C语言无关。 - thecoshman
何必猜测,当你有一个明确定义类型长度位置的ISO标准时? - slaphappy
2
标准规定long类型的大小至少应该与int类型相同,但并未规定其必须为4个字节,也没有解释为什么在Windows C/C++编译器中它是4个字节。在您给出负评之前,请仔细阅读答案。 - Roy Dictus

1

除了AProgrammer可能回答了你的实际问题,没有人回答。

C/C++标准的定义如Griwes所描述。这允许C和C++语言在编译器供应商可以定义最方便计算机架构大小的情况下进行实现。一段时间内(对于Windows 3.1及之前的版本,即Windows 95之前),Windows的C代码具有16位int,而许多UNIX平台(如Solaris、HPUX和AIX)具有32位int。

然而,现代微型计算机(自386以来)具有完整的32位寄存器,并且将内存对齐到32位比访问16位增量要快得多。因此,使用32位int的代码比使用16位int的代码更有效率,特别是对于int数组。

为了在32位寄存器中模拟16位int,您还必须在第16位上溢出,而不是第32位。因此,即使您只有32位可用于long,使用32位int也更容易。


0

我认为这取决于具体的实现。它们可能会有所不同,但供应商负责提供它们。然而,有些供应商只是让它们在语法上“支持”(即:你可以将它们放入代码中并编译通过,但没有区别)。偶尔会遇到这样的语言特性。


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