我被告知C类型取决于机器.今天我想验证它.
void legacyTypes()
{
/* character types */
char k_char = 'a';
//Signedness --> signed & unsigned
signed char k_char_s = 'a';
unsigned char k_char_u = 'a';
/* integer types */
int k_int = 1; /* Same as "signed int" */
//Signedness --> signed & unsigned
signed int k_int_s = -2;
unsigned int k_int_u = 3;
//Size --> short, _____, long, long long
short int k_s_int = 4;
long int k_l_int = 5;
long long int k_ll_int = 6;
/* real number types */
float k_float = 7;
double k_double = 8;
}
Run Code Online (Sandbox Code Playgroud)
我使用minGW C编译器在32位机器上编译它
_legacyTypes:
pushl %ebp
movl %esp, %ebp
subl $48, %esp
movb $97, -1(%ebp) # char
movb $97, -2(%ebp) # signed char
movb $97, -3(%ebp) # unsigned char
movl $1, -8(%ebp) # int
movl $-2, -12(%ebp)# signed int
movl $3, -16(%ebp) # unsigned int
movw $4, -18(%ebp) # short int
movl $5, -24(%ebp) # long int
movl $6, -32(%ebp) # long long int
movl $0, -28(%ebp)
movl $0x40e00000, %eax
movl %eax, -36(%ebp)
fldl LC2
fstpl -48(%ebp)
leave
ret
Run Code Online (Sandbox Code Playgroud)
我在GCC(linux)上的64位处理器(Intel Core 2 Duo)上编译了相同的代码
legacyTypes:
.LFB2:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
movq %rsp, %rbp
.cfi_offset 6, -16
.cfi_def_cfa_register 6
movb $97, -1(%rbp) # char
movb $97, -2(%rbp) # signed char
movb $97, -3(%rbp) # unsigned char
movl $1, -12(%rbp) # int
movl $-2, -16(%rbp)# signed int
movl $3, -20(%rbp) # unsigned int
movw $4, -6(%rbp) # short int
movq $5, -32(%rbp) # long int
movq $6, -40(%rbp) # long long int
movl $0x40e00000, %eax
movl %eax, -24(%rbp)
movabsq $4620693217682128896, %rax
movq %rax, -48(%rbp)
leave
ret
Run Code Online (Sandbox Code Playgroud)
意见
char,signed char,unsigned char,int,unsigned int,signed int,short int,unsigned short int,signed short int all占用相同的no.32位和64位处理器上的字节数.
唯一的变化是在long int与long long int这两个占据64位机器上的32位机器和64位上的32位.
还有指针,它们在32位CPU上采用32位,在64位CPU上采用64位.
问题:
编辑:
是不是不可能在不同的机器上提供相同的尺寸?我的意思是,如何在64位和32位机器上保持相同的指针大小?
那里有更多的平台,其中一些是16位甚至8位!在这些方面,您会发现所有上述类型的尺寸差异更大.
相同基本类型的有符号和无符号版本在任何平台上占用相同的字节数,但是它们的数字范围是不同的,因为对于带符号的数字,在有符号和无符号域之间共享相同范围的可能值.
例如,16位带符号的int可以具有从-32767(或许多平台上的-32768)到32767的值.相同大小的无符号int在0到65535的范围内.
在此之后,希望您更好地理解所提问题的重点.基本上如果你编写一个程序,假设例如你的signed int变量将能够保持2*10 ^ 9(20亿)的值,那么你的程序是不可移植的,因为在某些平台上(16位及以下)这个值会导致溢出,导致沉默,很难找到错误.因此,例如一个16位的平台,你需要在#define你的整数是long为了避免溢出.这是一个简单的例子,可能无法在所有平台上运行,但我希望它能为您提供一个基本的想法.
平台之间所有这些差异的原因是,在C标准化的时候,已经有许多C编译器在过多的不同平台上使用,因此为了向后兼容,所有这些变量都必须被认为是有效的.