为什么C编译器将long指定为32位,而将long long指定为64位?

11

如果使用64位长整型并将long long保留到128位变成现实的时候,这样做是否更合理?


1
两件事情:首先,long long 不一定是 64 位。其次,建议将其宽度设为 128 位同样是狭隘的想法 - 我们应该为 1024 位硬件变得普遍做好准备,对吧? - Mac
1
实际上,“C编译器”并没有规定long是32位,也没有规定int是32位,也没有规定long long是64位。这完全取决于编译器...所以你的问题基于错误的前提。 - Nemo
2
他们最终在 C99 中实现了这个功能:http://en.wikipedia.org/wiki/Stdint.h - Mysticial
2
@seljuq70:long long不能被“保留”,因为C99标准保证了它的存在。在一个16位系统上,有一个16位的int,32位的long和64位的long long,它们都是不同的,但是对于桌面机来说,那些日子已经过去了。我们不会坚持使用16位的int,只是为了避免感觉中间有一个多余的类型。 - Steve Jessop
1
@Eugene - 关于为什么并非所有问题都可以通过标准解决的另一讨论,请参见此问题Exotic-architectures-the-standard-committee-cares-about - Bo Persson
显示剩余8条评论
7个回答

12

没错,这有意义,但是微软有他们自己的原因将“long”定义为32位。

据我所知,目前所有主流的系统中,Windows是唯一一个“long”为32位的操作系统。在Unix和Linux上,“long”是64位。

所有Windows的编译器都会将“long”编译成32位以保持与Microsoft的兼容性。

出于这个原因,我避免使用“int”和“long”。偶尔我会在C语言中将“int”用于错误代码和布尔值,但我从不将它们用于依赖类型大小的任何代码。


2
我在32位足够大的情况下使用long,而且我不想在我的代码中到处使用int32_least_t或自己的typedef。最好明确和显式地表明依赖关系,如果它在结构体中,则可能会使用int32_t以避免在long更大的情况下膨胀,但是总有一个“无法处理这个”的点。 - Steve Jessop
2
许多嵌入式设备(2015年每年数十亿)使用32位的“long”。几乎没有“所有主流系统...都是64位”的情况。 - chux - Reinstate Monica

5
C标准并没有规定原始数据类型的位数长度,只规定了它们的最小位数长度。因此,编译器可以在原始数据类型的位数长度上有选择性。在决定每种原始数据类型的位数长度时,编译器设计者应该考虑多种因素,包括计算机体系结构。
以下是一些参考资料: http://en.wikipedia.org/wiki/C_syntax#Primitive_data_types

3

关于历史,包括为什么UNIX系统通常会收敛到LP64,而Windows没有(有一个大的代码库,其中int 16和long 32),以及各种争论:

《漫长的64位之路》- 双倍、双倍,劳动和麻烦——莎士比亚,《麦克白》

https://queue.acm.org/detail.cfm?id=1165766 Queue 2006 或者 https://dl.acm.org/doi/pdf/10.1145/1435417.1435431 CACM 2009

注意:我曾参与设计64/32位MIPS R4000,提出了导致<inttypes.h>的想法,并为C99编写了长整型的动机部分。


2
由于历史原因。很长一段时间,“int”代表16位;因此“long”代表32位。当然,时代在变化。因此出现了“long long” :)
PS:
GCC(和其他编译器)目前支持128位整数作为“(u)int128_t”。
PPS:
这里有一个讨论,讲述了GCC的开发人员为什么做出这些决定:

http://www.x86-64.org/pipermail/discuss/2005-August/006412.html


0
32位微型计算机将“char”定义为8位,“short”定义为16位,“long”定义为32位。它们之间唯一的区别在于“int”是16位还是32位。
虽然32位或更大的CPU可以将“int”用作32位类型,使“long”可用作64位类型,但有大量的代码期望“long”为32位。虽然C标准在1999年添加了“固定大小”的类型,但标准中仍有其他地方使用“int”和“long”,例如“printf”。 虽然C99添加了宏来提供

0

自从第一个通用可重编程微型计算机的C编译器问世以来,代码经常需要使用恰好包含8、16或32位的类型,但直到1999年标准并未明确提供程序指定的方式。另一方面,几乎所有8位、16位和32位微型计算机的编译器都将“char”定义为8位,“short”定义为16位,“long”定义为32位。它们之间唯一的区别在于“int”是16位还是32位。

虽然32位或更大的CPU可以使用“int”作为32位类型,将“long”留作64位类型,但有一个大量的代码库期望“long”将是32位。虽然C标准在1999年添加了“固定大小”的类型,但标准中仍有其他地方使用“int”和“long”,例如“printf”。虽然C99添加了宏来提供固定大小整数类型的正确格式说明符,但有大量的代码期望“%ld”是int32_t的有效格式说明符,因为它可以在任何8位、16位或32位平台上工作。

无论是出于对几十年来现有代码库的尊重而使“long”成为32位,还是出于避免需要更冗长的“long long”或“int64_t”来标识64位类型的需要而使其成为64位,这可能是一个判断性的问题,但考虑到新代码应该在实际情况下优先使用指定大小的类型,我不确定是否有必要将“long”设置为64位,除非“int”也是64位(这将导致现有代码出现更大的问题)。


-2

C99 N1256标准草案

longlong long的大小是实现定义的,我们所知道的仅有:

  • 最小尺寸保证
  • 类型之间的相对大小

5.2.4.2.1 整数类型的大小 <limits.h> 给出了最小尺寸:

1 [...] 它们的实现定义值应等于或大于所示值的数量(绝对值)[...]

  • UCHAR_MAX 255 // 2 8 − 1
  • USHRT_MAX 65535 // 2 16 − 1
  • UINT_MAX 65535 // 2 16 − 1
  • ULONG_MAX 4294967295 // 2 32 − 1
  • ULLONG_MAX 18446744073709551615 // 2 64 − 1

6.2.5 类型 然后说:

对于任何两个具有相同符号性和不同整数转换等级(参见6.3.1.1)的整数类型,较小整数转换等级的类型的值范围是另一类型值范围的子集。
“6.3.1.1布尔、字符和整数”决定了相对转换等级:
1.每种整数类型都有一个整数转换等级,定义如下: - long long int的等级应大于long int的等级,long int的等级应大于int的等级,int的等级应大于short int的等级,short int的等级应大于signed char的等级。 - 任何无符号整数类型的等级应等于相应的有符号整数类型(如果有)的等级。 - 对于所有整数类型T1,T2和T3,如果T1比T2具有更高的等级,T2比T3具有更高的等级,则T1比T3具有更高的等级。

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