什么定义了类型的大小?

What defines the size of a type?

ISO C 标准说:

sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long)

我在 BIT Linux mint (19.1) 上使用 GCC-8,long int 的大小是 8

我正在使用一个使用 GCC 7 且编译器为 64 位的应用程序。 long int 的大小是 4。 编译器或操作系统是否定义了long int的大小?

编译器做主。操作系统只运行生成的二进制文件。

也就是说,编译器通常会生成操作系统可以使用的可执行文件,因此这里存在一些相互作用。因为 int 的大小并不重要 只要它们一致 ,你就会看到变化。

换句话说,如果内核因为它的编译方式而期望 long int 为 8 个字节,那么您将希望以这种方式编译以匹配,否则您的编译代码将不匹配并且 none 个共享库将起作用。

操作Application Binary Interface指定基本类型的大小system/architecture:

ABI 涵盖了诸如(加粗我的)这样的细节:

  • a processor instruction set (with details like register file structure, stack organization, memory access types, ...)
  • the sizes, layouts, and alignments of basic data types that the processor can directly access
  • the calling convention, which controls how functions' arguments are passed and return values are retrieved; for example, whether all parameters are passed on the stack or some are passed in registers, which registers are used for which function parameters, and whether the first function parameter passed on the stack is pushed first or last onto the stack
  • how an application should make system calls to the operating system and, if the ABI specifies direct system calls rather than procedure calls to system call stubs, the system call numbers
  • and in the case of a complete operating system ABI, the binary format of object files, program libraries and so on.

这由实施自行决定。

实现(编译器和标准库)定义了longint和所有其他类型的大小。

只要它们符合标准给出的约束,实现就可以决定类型的大小(可能指针除外)。

TL/DR - 确切大小取决于编译器。


标准要求类型能够表示最小 值范围 - 例如,unsigned char 必须能够表示 至少范围[0..255],一个int必须能够表示至少范围[-32767...32767],等等

最小范围定义了最小位数 - 您至少需要 16 位来表示范围 [-32767..32767](某些系统可能使用填充位或奇偶校验位是单词的一部分,但不用于表示值)。

其他架构考虑因素开始发挥作用 - int 通常 设置为与本机字大小相同的大小。所以在 16 位系统上,int(通常)是 16 位,而在 32 位系统上它是 32 位。所以,最终,它归结于编译器。

但是,32 位系统上的一个编译器可以使用 16 位 int,而另一个使用 32 位 int。这导致我在 90 年代中期浪费了一个下午,当时我编写了一些代码,假设 32 位 int 在一个编译器下运行良好,但 打破了世界 同一硬件上的不同编译器。

所以,吸取教训 - 永远不要假设类型可以表示标准保证的最小值之外的值。检查 limits.hfloat.h 的内容以查看类型是否足够大,或者使用 stdint.h 中的一种大小类型(int32_tuint8_t, ETC。)。