编译后的 C 数据类型大小
C datatypes size after compilation
问题如下:C编程语言是否定义了编译器生成的可执行文件应如何根据数据大小类型进行格式化?为了更好地解释这一点,假设我编译了一个 C 源代码文件,其中包含一个名为 'x' 的 int 类型变量。我成功地将源代码编译成可执行文件并 运行 它。在 运行 期间,分配给 'x' 的内存位置为 4 字节宽,并根据 2 的补码标准进行结构化。
如果我要 运行 来自具有相同操作系统和兼容 CPU 的不同机器的相同编译可执行文件,我是否可以保证变量始终为 4格式完全相同的字节宽(意味着完全相同的位占用空间)?我知道 C 对于基本类型有可变的数据大小,这只适用于预编译代码。但是 post-编译代码呢?如果 int 在一台为其分配 32 位的机器上转换为汇编程序 DWORD 数据类型,是否可以保证它在另一台机器上采用 32 位的形式? DWORD 在同一型号的不同 CPU 中是否始终相同?
我一直认为编译只是建立所有实现细节和 'setting in stone' 内存中数据类型的确切大小和内部格式的过程,但我想要一些确认。另外,这也适用于 C++ 吗?
If I were to run the same compiled executable from a different machine with the same operating system and a compatible CPU, do I have any guarantee that the variable will at all times be 4 bytes wide in the exact same format
C 标准不能保证,但会保证。这将由编译后的机器码决定。
在 C 级别以下,编译器也遵守一些 "application binary interface"(缩写为 ABI;不要与 API 混淆)。这就是让这些细节一成不变的原因。应用程序二进制接口定义类型的大小和整数的表示,以及 很多 其他内容,例如如何将参数传递给函数。
一个平台可以支持多个 ABI。例如,在 Windows 上,您拥有本机 ABI,并且可以安装 Cygwin,它可以让您 运行 程序的 ABI 更接近 Linux。然而,假设两台不同的机器支持相同的 ABI,那么是的,它们之间共享可执行文件保证工作(假设所需的库等存在)并且保证一切都具有兼容的表示。
这在原理上与 C++ 相同。
在许多地方,C 标准要求编译时可用的任何信息必须 "as-if" 在所有可能的执行环境中保持不变。这至少包括:
- 所有类型的大小和对齐方式(
sizeof
和 _Alignof
,尽管没有后者也可以实现对齐方式)
- 算术类型的值范围,因为它们可以通过
#include <limits.h>
和 #include <float.h>
访问。
- 如果值范围和大小限制它,内部布局(负数的补充格式,并且没有填充 bits/trap 表示)。比如
SCHAR_MIN
是-128(只要求<=-127),CHAR_BIT
是8,那么保证2的补码是8位signed char
.
尽管如此,可以根据运行时系统改变很多东西(无论是理论上还是实际上)。
问题如下:C编程语言是否定义了编译器生成的可执行文件应如何根据数据大小类型进行格式化?为了更好地解释这一点,假设我编译了一个 C 源代码文件,其中包含一个名为 'x' 的 int 类型变量。我成功地将源代码编译成可执行文件并 运行 它。在 运行 期间,分配给 'x' 的内存位置为 4 字节宽,并根据 2 的补码标准进行结构化。
如果我要 运行 来自具有相同操作系统和兼容 CPU 的不同机器的相同编译可执行文件,我是否可以保证变量始终为 4格式完全相同的字节宽(意味着完全相同的位占用空间)?我知道 C 对于基本类型有可变的数据大小,这只适用于预编译代码。但是 post-编译代码呢?如果 int 在一台为其分配 32 位的机器上转换为汇编程序 DWORD 数据类型,是否可以保证它在另一台机器上采用 32 位的形式? DWORD 在同一型号的不同 CPU 中是否始终相同?
我一直认为编译只是建立所有实现细节和 'setting in stone' 内存中数据类型的确切大小和内部格式的过程,但我想要一些确认。另外,这也适用于 C++ 吗?
If I were to run the same compiled executable from a different machine with the same operating system and a compatible CPU, do I have any guarantee that the variable will at all times be 4 bytes wide in the exact same format
C 标准不能保证,但会保证。这将由编译后的机器码决定。
在 C 级别以下,编译器也遵守一些 "application binary interface"(缩写为 ABI;不要与 API 混淆)。这就是让这些细节一成不变的原因。应用程序二进制接口定义类型的大小和整数的表示,以及 很多 其他内容,例如如何将参数传递给函数。
一个平台可以支持多个 ABI。例如,在 Windows 上,您拥有本机 ABI,并且可以安装 Cygwin,它可以让您 运行 程序的 ABI 更接近 Linux。然而,假设两台不同的机器支持相同的 ABI,那么是的,它们之间共享可执行文件保证工作(假设所需的库等存在)并且保证一切都具有兼容的表示。
这在原理上与 C++ 相同。
在许多地方,C 标准要求编译时可用的任何信息必须 "as-if" 在所有可能的执行环境中保持不变。这至少包括:
- 所有类型的大小和对齐方式(
sizeof
和_Alignof
,尽管没有后者也可以实现对齐方式) - 算术类型的值范围,因为它们可以通过
#include <limits.h>
和#include <float.h>
访问。 - 如果值范围和大小限制它,内部布局(负数的补充格式,并且没有填充 bits/trap 表示)。比如
SCHAR_MIN
是-128(只要求<=-127),CHAR_BIT
是8,那么保证2的补码是8位signed char
.
尽管如此,可以根据运行时系统改变很多东西(无论是理论上还是实际上)。