我可以假设long int的大小始终为4个字节吗?


73

是否总是真的long int(这是我的理解是对的代名词long)是4个字节?

我可以依靠吗?如果不是,那么对于基于POSIX的操作系统来说是否正确?


12
只是提醒大家,请sizeof注意填充和对齐方式。它具有sizeof(unsigned long)8个字节的标准格式,但溢出的行为类似于4个字节。尝试使用sizeofCHAR_BITS计算整数类型的限制是错误的方式。使用limits.h时应使用。
user3528438

11
您确实应该阅读C-faq(首先是删节版,然后是完整版),它起源于Usenet,当时它是一个有知识的人聚集在同一地方的地方(现在,它在几个网站...),因此导致了难以置信的麻烦和做得好的FAQ。请参阅c-faq.com/versions.html。读它可以使这个问题大开眼界,还有数十个您甚至可能还不知道需要知道(第5节-空指针-是其中包含我被震惊(并感激)发现的常见问题解答)
Olivier Dulac

7
不,在我的电脑上是8
RiaD


3
在大多数64位系统(例如x86-64 Linux和OS X)上,它为8。Windows是主要的例外,因为为32位Windows编写的代码太多,而为32位Windows编写的代码很少,甚至没有做任何努力来编写未做假设的可移植代码。也是出于ABI的原因:我认为某些结构long的定义中带有s,但是它们不必是64位的。因此,MS决定使用long32位,以使其结构在ABI和现有代码库中保持相同的大小。
彼得·科德斯

Answers:


112

除了之外,标准没有关于任何整数类型的确切大小char。通常,long在32位系统上为32位,在64位系统上为64位。

但是,该标准并未指定最小尺寸。从C标准的5.2.4.2.1节开始:

1以下给出的值应被适合用于#if预处理指令的常量表达式代替。此外,除了CHAR_BIT和之外MB_LEN_MAX,以下内容应替换为与根据整数提升转换为相应类型的对象的表达式具有相同类型的表达式。 其实现定义的值的大小(绝对值)应等于或大于所示的相同符号。

...

  • 类型对象的最小值 long int

    LONG_MIN -2147483647 //-(2 ^ 31-1)

  • 类型对象的最大值 long int

    LONG_MAX +2147483647 // 2 ^ 31−1

这表示along int 必须至少为32位,但可能更大。在CHAR_BIT值为8的机器上,它的最小字节大小为4。但是,在例如CHAR_BIT等于16的机器上,along int可以为2个字节长。

这是一个真实的例子。对于以下代码:

在Debian 7 i686上的输出:

sizeof(long)= 4

在CentOS 7 x64上的输出:

sizeof(long)= 8

所以不,您不能对尺寸做任何假设。如果需要特定大小的类型,可以使用中定义的类型stdint.h。它定义了以下类型:

  • int8_t:签名的8位
  • uint8_t:无符号8位
  • int16_t:有符号16位
  • uint16_t:无符号16位
  • int32_t:签名的32位
  • uint32_t:无符号32位
  • int64_t:签名的64位
  • uint64_t:无符号64位

所述stdint.h报头在标准的第7.20节中描述7.20.1.1,具有精确宽度的类型。该标准指出这些typedef是可选的,但它们存在于大多数实现中。


4
但是这些typedef是标准的!只是实现定义了它们是否实际存在以及它们代表哪种类型!
文森特

10
@nouney不要混淆最小位数和最小字节数。我不记得有什么禁忌了1 == sizeof(char) == sizeof(int)。您能提供标准中的int至少2个字节”的报价吗?
jfs

4
@nouneychar可以大于8位。当然,拥有32位(sizeof当然仍然是1位)会使处理8位文本编码这样的数据变得很痛苦,但通常不会将类似的平台用于文本处理。
海德

6
我不会说这long通常是64位的,因为它不在Windows上,并且Windows被广泛使用。当然,标准本身并未对此进行定义,因此这两种实现都符合标准,但是最终结果是大量的unix C(和C ++)代码在Windows上截断了64位指针(只是停止将指针存储为整数) ,该死!当然,从根本上讲,这是由于使用标准范围为[−2147483647,+2147483647]的类型来存储大于该值的类型而造成的,这有点荒谬,但是好吧:)
Luaan

3
我一直了解到sizeof(char)<= sizeof(short)<= sizeof(int)<= sizeof(long),并且所有实现都已定义。
克里斯K

38

不,C标准和POSIX都不能保证这一点,事实上,大多数类似Unix的64位平台都具有64位(8字节)long


大多数32位及以上平台上的整数都是32位(无论如何还是AFAIK),那么拥有与整数相同大小的long的意义何在?在我的系统(Intel,64位Linux,gcc)上,int为32,长时间为64。
jamesqf

7
@jamesqf:在1980到2005年之间发布的绝大多数平台上,为实现方便,short是16位,long是32位,而“ int”是16或32位。在C99添加stdint.h之前为16位和32位类型设置固定大小的类型很有帮助。但是,作为后者的一个很好的附加复杂因素,在具有32位“ int”的系统上,int32_t可能与“ int”或“ long”兼容,但是不允许采用兼容的实现方式使其与两者兼容。
超级猫

19

使用代码sizeof(long int)并检查大小。它会为您提供当前正在使用的系统上long int的大小(以字节为单位)。您的问题的答案尤其是“否”。在C,POSIX或任何地方都无法保证。


2
海事组织,这不能回答问题。
诺尼,2016年

6
它实际上对我有帮助:)
消除

@nouney如何说明C标准没有确切的尺寸,或者POSIX标准无法回答问题?这不是最佳答案,但肯定没有错。
Leliel

3
@Leliel,因为当我发布评论时,anwser只是“使用sizeof”。
诺尼,2016年

sizeof(long int)将填充和对齐限制因素纳入其结果。sizeof即使只允许使用其中四个字节,返回“ 16”也是完全有效的。
2016年

13

正如@delnan所指出的那样,POSIX实现会保留的大小longint未指定的大小,并且在32位和64位系统之间通常有所不同。

其长度long主要与硬件有关(通常与CPU上数据寄存器的大小匹配,有时与其他软件相关的问题(例如OS设计和ABI接口)匹配)。

为了简化您的想法,sizeof它不是函数,而是编译器指令*,因此您的代码在使用时不使用操作sizeof-它与编写数字相同,只是可移植。

采用:

*正如Dave在注释中指出的那样,sizeof当无法在编译过程中计算值时(例如,使用可变长度数组时),将在运行时进行计算。

另外,正如另一条评论中指出的那样,sizeof考虑到实现所使用的填充和对齐方式,这意味着使用的实际字节可能与内存中的大小不同(这在移位时很重要)。

如果要查找特定的字节大小的变量,请考虑使用字节数组或(我假设会支持)由C99 stdint.hin-定义的类型,如@dbush所建议。


4
不是(仅仅是)硬件。您可以在64位硬件上运行32位Linux,甚至可以使用x32 ABI,其中数据类型的大小与32位硬件上的大小相同,但硬件实际上以64位模式运行。

@delnan,是的。我可能应该通过更改usuallymostly并在括号中添加信息来阐明这一点。
Myst

@delnan,我并不是要超越您的答案,我只是想最好弄清楚这sizeof是一个编译器指令,以消除任何人可能会猜到的大小的可感知原因。
Myst

1
小校正:sizeof在(如果使用)在C99或更高版本中使用可变长度数组或可变修改的类型(或“ gnu89”作为GCC扩展名)时,在运行时进行计算,但大多数代码不这样做。
dave_thompson_085 '16

13

当我们首次在ICL Series 39硬件上实现C时,我们一字不漏地使用了标准,并将数据类型映射到该计算机体系结构上的自然表示形式,即short32位int= 64位long= 128位。

但是我们发现没有任何认真的C应用程序可以工作。他们都假定映射short= 16 int= 32 long= 64,我们必须更改编译器以支持该映射。

因此,不管官方标准说什么,多年来,每个人都汇聚了long= 64位,并且这种可能性不太可能改变。


2
真?至少在GCC / Glibc / GNU / Linux上,平台似乎在int = 32,long long = 64,long =本机字大小(32或64)以及肯定不是long = 64上收敛。例如在x86上,不完全是利基架构,长是32位。OSX,Solaris,z / OS,SysV是遵循此约定的其他一些操作系统。
约尔格W¯¯米塔格

对于比OSX,Linux,z / OS或SysV更为广泛使用的系统,有Windows,它与您(总是64个)或那些(总是与指针相同)的约定又不同,即始终为32位。
约尔格W¯¯米塔格

恕我直言,适当的补救措施是拥有一种标准的方法,通过该方法,代码可以指定在某些上下文中(通常是每个文件,从而使标头文件声明一个函数为:接受“ int”将始终具有相同的含义]。让64位系统模拟16位或32位“ int”应该是相当简单的,并且可能比给定C语言中所有奇妙的细微差别来尝试调整代码更可靠(例如在64位系统上位系统,uint32_t模块化乘法不适用于所有值)。
超级猫

11

标准没有说明的大小long int,因此它取决于您使用的环境。

要获取long int您环境中的大小,可以使用sizeof运算符并获取的大小long int。就像是

C标准仅要求有关类型大小的以下几点

  • int> = 16位,
  • 长于== 32位,
  • long long(因为C99)> = 64位
  • sizeof(char)<= sizeof(short)<= sizeof(int)<= sizeof(long)<= sizeof(long long)
  • sizeof(char)== 1
  • CHAR_BIT> = 8

剩下的是定义的实现,因此如果遇到某些系统具有int有18/24/36/60位,一个补码形式的系统,sizeof(char)== sizeof(short)== sizeof(int)== sizeof(long)== 4、48位长或9位char,类似于标准委员会关注的Exotic体系结构以及C标准支持的平台列表

关于上面的long int的观点是完全错误的。大多数Linux / Unix实现将长定义为64位类型,但在Windows中只有32位,因为它们使用不同的数据模型(请参见此处的表64位计算),而无论32位还是64位操作系统版本。

资源




0

简短的回答:不!您无法对的大小做出固定假设long int。因为,该标准(C标准或POSIX)未记录其大小long int(反复强调)。只是为了提供您所相信的反例,大多数64位系统long的大小为64!为了最大程度地提高便携性,请sizeof适当使用。

使用sizeof(long int)检查大小,它返回的大小long以字节为单位。该值取决于系统或环境;意思是,编译器根据硬件和操作系统确定大小。


0

来自Usrmisc的博客:

该标准完全由编译器决定,这也意味着同一编译器可以使其依赖于选项和目标体系结构。

所以你不能

顺便说一句,甚至long int可能与相同long


这个答案有什么问题?为什么有人给她一个负面的观点?毕竟,它是对问题的答案,与其他答案相比,它的简单性使其与众不同,这对某些正在寻找答案的人来说可能很重要。是不是
simhumileco
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.