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

Can I assume the size of long int is always 4 bytes?

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

我可以依靠它吗?如果不是,那么对于基于 POSIX 的 OS 是否成立?

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

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

1 The values given below shall be replaced by constant expressions suitable for use in #if preprocessing directives. Moreover, except for CHAR_BIT and MB_LEN_MAX, the following shall be replaced by expressions that have the same type as would an expression that is an object of the corresponding type converted according to the integer promotions. Their implementation-defined values shall be equal or greater in magnitude (absolute value) to those shown, with the same sign.

...

  • minimum value for an object of type long int

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

  • maximum value for an object of type long int

    LONG_MAX +2147483647 // 2^31−1

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

这是一个 real-world 示例。对于以下代码:

#include <stdio.h>

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

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 header 在标准的第 7.20 节中描述,在第 7.20.1.1 节中有确切的宽度类型。标准声明这些 typedef 是可选的,但它们存在于大多数实现中。

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

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

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

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

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

使用:

sizeof(long int)

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

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

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

编译器根据硬件类型和OS确定大小。

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

当我们第一次在 ICL 39 系列硬件上实现 C 语言时,我们按照标准的原话将数据​​类型映射到该机器架构上的自然表示,即 short = 32 位,int = 64 位,long = 128 位。

但是我们发现没有任何严肃的 C 应用程序可以工作;他们都假定映射 short = 16,int = 32,long = 64,我们不得不更改编译器以支持它。

所以无论官方标准怎么说,多年来每个人都集中在 long = 64 位并且不太可能改变。

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

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

sizeof(long int)

C standard only requires the following points about the sizes of types

  • int >= 16 bits,
  • long >= 32 bits,
  • long long (since C99) >= 64 bits
  • sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long)
  • sizeof(char) == 1
  • CHAR_BIT >= 8

The remaining are implementations defined, so it's not surprised if one encountered some systems where int has 18/24/36/60 bits, one's complement signed form, sizeof(char) == sizeof(short) == sizeof(int) == sizeof(long) == 4, 48-bit long or 9-bit char like Exotic architectures the standards committees care about and List of platforms supported by the C standard

The point about long int above is completely wrong. Most Linux/Unix implementations define long as a 64-bit type but it's only 32 bits in Windows because they use different data models (have a look at the table here 64-bit computing), and this is regardless of 32 or 64-bit OS version.

Source

来自Usrmisc's Blog:

The standard leaves it completely up to the compiler, which also means the same compiler can make it depend on options and target architecture.

所以你不能

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

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

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

确定大小

不,您不能这样假设,因为“long”数据类型的大小因编译器而异。
查看 this 文章了解更多详情。