C中基本数据类型的大小

我有一个示例程序,我从一些网站复制。

int main(void) { int answer; short x = 1; long y = 2; float u = 3.0; double v = 4.4; long double w = 5.54; char c = 'p'; typedef enum { kAttributeInvalid, kBooleanAttributeActive, kBooleanAttributeAlarmSignal, kBooleanAttributeAlign64, kBooleanAttributeAutoNegotiationComplete, }codes_t; /* __DATE__, __TIME__, __FILE__, __LINE__ are predefined symbols */ #if 0 printf("Date : %s\n", __DATE__); printf("Time : %s\n", __TIME__); printf("File : %s\n", __FILE__); printf("Line : %d\n", __LINE__); #endif /* The size of various types */ printf("The size of int %zu\n", sizeof(answer)); printf("The size of short %zu\n", sizeof(x)); printf("The size of long %zu\n", sizeof(y)); printf("The size of float %zu\n", sizeof(u)); printf("The size of double %zu\n", sizeof(v)); printf("The size of long double %zu\n", sizeof(w)); printf("The size of char %zu\n", sizeof(c)); printf("The size of enum %zu\n", sizeof(codes_t)); return 0; } 

我运行这个程序,我得到的输出如下。

 The size of int 4 The size of short 2 The size of long 8 The size of float 4 The size of double 8 The size of long double 16 The size of char 1 The size of enum 4 

我在运行64位Ubuntu的Linux PC上运行它。我的问题是,如果我在32位机器上运行相同的程序,我会看到不同的结果。或者换句话说,基本数据的大小类型取决于

  1. 处理器
  2. 操作系统
  3. 还要别的吗

如果必须在其32位变体中安装一些库[可能只是glibc],您应该可以使用gcc -m32 myprog.c [或clang -m32 myprog.c ] clang -m32 myprog.c

但是,如果您使用基于gcc的编译器从64位x86 linux系统迁移到32位x86 linux系统,那么列出的项目中唯一会改变的是大小。 注意x86,gcc等的重要资格 – 编译器有很多自由。 有人可以为Linux编写一个编译器,它在32位系统上使用16位int和64位long ,没有太大的难度。 使用该编译器编译Linux内核和许多Linux工具可能会失败[很可能包括使用该编译器编译gcc ]。 但你不能真正说“在这个体系结构上”或“在这个操作系统中”或“使用这个编译器”…而且还没有限定其他参数是什么。

例证:即使在64位系统上,Microsoft C / C ++编译器的long也是32位。 为什么,我听到你问? 因为当Windows是Intel 286/386处理器上的16位操作系统时,大量的Windows API函数使用long的32位值作为遗留。 由于(部分)系统调用在Windows中向后兼容很长,因此为16位系统编写的代码仍可在64位Windows上运行[除非代码使用了一些非常不寻常的系统调用,当然,STYLE看起来有点古老]。 将long改为64位值会破坏一些function,因此MS的编译器人员决定坚持使用long = 32位。 如果你想要64位整数,你必须使用long longint64_t或其他东西,不long 。 当然,这会破坏一些假定sizeof(long) == sizeof(void *) 。 希望大多数此类代码已经修复……

我的问题是,如果我在32位机器上运行相同的程序,我会看到不同的结果

也许。 或者可能不是。

或者换句话说,基本数据类型的大小取决于1)处理器2)操作系统3)其他任何东西

  1. 是的,2。是的,3。是的,例如,如果您在64位操作系统上以32位兼容模式运行32位应用程序,那么它很可能会使用32位字大小(当然,它像那样编译)。 哦,是的,它可能还取决于编译器。

“而你的编译器标志……” (谢谢,凯!)

如果你关心变量使用的确切大小

 #include  

然后使用那里定义的固定宽度类型:

 uint8_t uint16_t uint32_t uint64_t 

或他们签名的堂兄弟

 int8_t int16_t int32_t int64_t 

不要依赖C中本机类型的大小。不同的编译器有不同的规则。

是的,在某些情况下,它取决于硬件,操作系统,编译器甚至语言。

但是在x86 linux上,longs将是32位平台上的4个字节,而不是8个。其他我相信所有都保持不变(不确定长双倍)。

轶事:

我曾经在一个24位系统上工作,其字大小为24位,每个本机类型的大小为1个字。 的sizeof(字符)? 1(即:24位)。 的sizeof(int)的? 1(即:24位)。 等等!好玩!

这些大小由编译器在编译时设置,因为编译器必须发出特定于大小的指令,在结构中布置成员,并知道所有必需地址计算的结构大小。

因此,如果将源代码编译为64位二进制文​​件并在一堆不同的系统上运行,则每次运行时类型将具有相同的大小,如果系统支持二进制文件的话。

如果您然后将源代码编译为32位二进制文​​件或使用不同的编译器开关,当您在一堆不同的系统上运行它时,那么数字可能与64位情况不同,但它们将在所有不同的情况下保持一致系统。