我可以假设long int的大小总是4个字节吗?

时间:2016-03-07 13:07:46

标签: c linux types posix

long int(据我所知是long的同义词)是4个字节,总是这样吗?

我可以依靠吗?如果没有,对于基于POSIX的操作系统是否属实?

10 个答案:

答案 0 :(得分:105)

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

但标准确实指定了最小大小。来自C Standard的第5.2.4.2.1节:

  

1 下面给出的值应该用常量表达式替换   适用于#if预处理指令。此外,   除了CHAR_BITMB_LEN_MAX之外,以下内容如下:   替换为与a具有相同类型的表达式   表达式,是转换的相应类型的对象   根据整数促销。 他们的实现定义   值的大小(绝对值)应等于或大于   显示的那些,具有相同的符号。

     

...

     
      
  • long int

    类型对象的最小值      

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

  •   
  • long int

    类型的对象的最大值      

    LONG_MAX +2147483647 // 2 ^ 31-1

  •   

这表示long int 必须至少为32位,但可能更大。在CHAR_BIT为8的机器上,这给出了最小字节大小为4.但是在具有例如4的机器上。 CHAR_BIT等于16,long int可能是2个字节长。

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

#include <stdio.h>

int main ()
{
    printf("sizeof(long) = %zu\n", sizeof(long));
    return 0;
}

Debian 7 i686上的输出:

  

sizeof(长)= 4

CentOS 7 x64上的输出:

  

sizeof(长)= 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是可选的,但它们存在于大多数实现中。

答案 1 :(得分:38)

不,C标准和POSIX都不能保证这一点,实际上most Unix-like 64-bit platforms有64位(8字节)long

答案 2 :(得分:20)

使用代码sizeof(long int)并检查尺寸。它将在您当前正在工作的系统上为您提供长整数字节的大小。特别是你的问题的答案是否定的。在C或POSIX或任何地方都无法保证。

答案 3 :(得分:14)

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

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

为了让您放心,sizeof不是函数,而是编译器指令*,因此您的代码在使用sizeof时不会使用操作 - 它是&#39}与编写一个数字相同,只是它的便携性。

使用:

sizeof(long int)

*正如Dave在评论中指出的那样,sizeof将在运行时计算,因为在编译期间无法计算值,例如使用可变长度数组时。

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

如果您正在寻找特定字节大小的变量,请考虑使用字节数组或(我认为支持)C99在stdint.h中定义的类型 - 正如@dbush所建议的那样。

答案 4 :(得分:13)

当我们首次在ICL Series 39硬件上实现C时,我们采用了标准,并将数据类型映射到该机器架构上的自然表示,即short = 32位,{{1} } = 64位,int = 128位。

但我们发现没有严肃的C应用程序有效;他们都假设映射long = 16,short = 32,int = 64,我们必须更改编译器以支持它。

因此无论官方标准如何说,多年来每个人都在long = 64位上收敛,而且不太可能改变。

答案 5 :(得分:10)

standardlong int的大小一无所知,因此它取决于您使用的环境。

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

这样的东西
sizeof(long int)
  

C标准只需要关于类型大小的以下几点

     
      
  • int&gt; = 16位,
  •   
  • long&gt; = 32位,
  •   
  • long long(自C99起)&gt; = 64位
  •   
  • sizeof(char)&lt; = sizeof(short)&lt; = sizeof(int)&lt; = sizeof(long)&lt; = sizeof(long long)
  •   
  • sizeof(char)== 1
  •   
  • CHAR_BIT&gt; = 8
  •   
     

其余的是定义的实现,所以如果,它并不感到惊讶   一个人遇到了一些系统,其中int有18/24/36/60位,一个是   补码表格,sizeof(char)== sizeof(短)== sizeof(int)   == sizeof(long)== 4,48位长或9位字符,如标准委员会关心的Exotic架构和List of   C标准支持的平台

     

关于long int的观点是完全错误的。大多数Linux / Unix   实现定义为64位类型,但它只有32位   Windows,因为他们使用不同的数据模型(看看   table here 64-bit computing),这不管是32位还是64位   操作系统版本。

Source

答案 6 :(得分:8)

编译器根据硬件类型和操作系统确定大小。

因此,不应对大小做出假设。

答案 7 :(得分:1)

来自Usrmisc's Blog:

  

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

所以你不能。

顺便提一句,long intlong相同。

答案 8 :(得分:1)

不,您不能假设由于“长”数据类型的大小因编译器而异。
查看this文章以了解更多详细信息。

答案 9 :(得分:0)

简答:不!您不能对long int的大小做出固定的假设。因为,标准(C标准或POSIX)没有记录long int的大小(如反复强调的那样)。为了给您的信念提供一个反例,大多数64位系统的大小为64 long!要最大限度地提高可移植性,请适当使用sizeof

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