为什么C数据类型在这台机器上有这些特定的大小?

我注意到C数据类型的大小可能会有所不同 。 我想知道这台机器产生的具体尺寸是什么原因

$ cat sizes.c int main() { printf("void *:%ld\n", sizeof(void *)); printf("char:%ld\n", sizeof(char)); printf("short:%ld\n", sizeof(short)); printf("int:%ld\n", sizeof(int)); printf("long:%ld\n", sizeof(long)); printf("long long:%ld\n", sizeof(long long)); printf("float:%ld\n", sizeof(float)); printf("double:%ld\n", sizeof(double)); printf("long double:%ld\n", sizeof(long double)); return 0; } $ ./sizes void *:8 char:1 short:2 int:4 long:8 long long:8 float:4 double:8 long double:16 

这是因为我的机器是:

  • Linux呢?
  • 64位?
  • Ubuntu的?
  • 旧?
  • 桌面发行版? (而不是移动,即Android)
  • 充满鳗鱼?
  • 使用英特尔处理器?
  • 用GCC编译?
  • 别的什么?

以下是系统详细信息:

 $ uname -a Linux melancholy 3.13.0-46-generic #77-Ubuntu SMP Mon Mar 2 18:23:39 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux $ cat /etc/issue Ubuntu 14.04.2 LTS \n \l $ cat /proc/version Linux version 3.13.0-46-generic (buildd@tipua) (gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) ) #77-Ubuntu SMP Mon Mar 2 18:23:39 UTC 2015 $ cat /proc/cpuinfo processor : 0 vendor_id : GenuineIntel cpu family : 6 model : 60 model name : Intel(R) Core(TM) i5-4460 CPU @ 3.20GHz stepping : 3 microcode : 0x12 cpu MHz : 3201.000 cache size : 6144 KB physical id : 0 siblings : 4 core id : 0 cpu cores : 4 apicid : 0 initial apicid : 0 fpu : yes fpu_exception : yes cpuid level : 13 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm ida arat epb xsaveopt pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid bogomips : 6400.67 clflush size : 64 cache_alignment : 64 address sizes : 39 bits physical, 48 bits virtual power management: ... Another three identical processors ... 

澄清一下,我并不是说系统有任何问题。 相反,我想知道为什么这些值是它们是什么,以便我可以预测它们将在哪些系统上不同,以便我可以编写可移植代码。

模型有LP64 ,意思是指针,长是64位; 这是Linux上的AMD64和更多平台的标准; 另一种是Windows LLP64 ,其中只有long long 64位宽, long是32位。

通常的选择是: char是最小的可寻址单元,最好是8位。 sizeof(short)至少为2; 如果处理器支持这个,那就这样吧。 int通常被选为最快的整数类型 – 在64位模式下的AMD64架构上32位寄存器比16位或64位寄存器使用更快或更受支持(16位和64位寄存器模式需要前缀字节) 。

现在,Windows使用LLP64的原因在于兼容性 – 许多代码都假设long为32位; 同样在Unix世界中,假设指针适合long – 现在指针是64位,那么long必须匹配该宽度。


要编写可移植程序,请包含并在那里使用常量; 否则假设这些类型的最小大小(int 2字节等)。 对于整数变量,使用intptr_t / uintptr_t也应该足够宽以容纳指针 – 或者使用union。

我认为可以肯定地说,从实际的角度来看,驱动力可能就是处理器。

处理器的相关架构无疑会对int的大小是否确实发生变化产生影响,但如果你的目标是超过1个特定处理器(例如,intel i3 530),那么你会想要记住它。

32位英特尔奔腾与64位英特尔奔腾。

手机中的arm9与台面POS机中的arm11。

等等

处理此问题的一种方法是使用int32_t,uint64_t和朋友。 如果可用,这些将保证相同的大小:uint32_t等32位。