根据 C99§5.2.4.2.1-1,以下类型的大小取决于实现。也就是说,它们的大小等于或大于以下值:
short >= 8 bits
int >= 16 bits
long >= 32 bits
long long >= 64 bits
我一直听说long
始终是32-bits
,它严格等同于看起来错误的int32_t
。
什么是真的?
答案 0 :(得分:5)
在我的计算机上,Linux中的长度为64位。
Windows是唯一在64位模式下使用32位long的主要平台,这完全是因为在现有代码中普遍存在错误的假设。这使得很难在Windows上更改long的大小,因此在64位x86处理器上,Windows中long仍为32位,以保持各种现有代码和定义的兼容性。
答案 1 :(得分:3)
根据定义,该标准是正确的,并且您解释它的方式也是正确的。某些类型的大小可能会有所不同。该标准仅规定了这些类型的最小宽度。通常(但不一定)类型int
具有与目标处理器相同的宽度。
这可以追溯到过去,在那儿,性能是非常重要的方面。例如,每当您使用int
时,编译器都可以选择仍保留至少 16位的最快类型。
当然,今天这种方法不是很好。这只是我们必须忍受的。是的,它可以破坏代码。因此,如果您想编写完全可移植的代码,请使用stdint.h
中定义的类型,例如int32_t
等。或者至少,如果您希望变量保存的数字不在int
范围内,请不要使用[−32,767; 32,767]
。
答案 2 :(得分:3)
我一直听说
long
始终是32位,并且严格等同于int32_t
,看起来很错误。
我很好奇你在哪里听到的。绝对错。
有很多系统(我认为大多数是16位或32位系统或64位Windows),其中long
是32位,但是也有很多系统在{{1} }是64位。
(即使long
是32位,也可能与long
的类型不同。例如,如果int32_t
和int
都是32位,它们仍然是不同的类型,long
可能被定义为另一个。)
int32_t
整数类型的大小要求几乎是 ,如您在问题中所指出的($ cat c.c
#include <stdio.h>
#include <limits.h>
int main(void) {
printf("long is %zu bits\n", sizeof (long) * CHAR_BIT);
}
$ gcc -m32 c.c -o c && ./c
long is 32 bits
$ gcc -m64 c.c -o c && ./c
long is 64 bits
$
的大小错误)。该标准实际上以范围而不是大小来陈述其要求,但是与二进制表示的要求一起意味着以位为单位的最小大小。要求是:
short
,char
,unsigned char
:8位signed char
,short
:16位unsigned short
,int
:16位unsigned int
,long
:32位unsigned long
,long long
:64位每个签名类型的范围都包括列表中上一个类型的范围。没有上限。
unsigned long long
和int
通常分别为32位和64位,尤其是在非Windows 64位系统上。 (POSIX要求long
至少要32位。)int
在我见过的每个系统上都是64位,尽管它可以更宽。
答案 3 :(得分:0)
请注意,标准未为int
,short
,long
等类型指定 size ,而是为 minimum这些类型必须能够代表的值范围。
例如,一个int
必须能够至少表示 范围[-32767..32767]
1 ,这意味着它必须是 at至少 16位宽。它可能更宽,原因有两个:
该平台提供了更多的值位以存储更大的范围(例如,x86使用32位存储整数值,使用64位存储长整数);
平台使用填充位存储除值的一部分以外的其他内容。
以后者为例,假设您有一个带18位字的9位平台。对于18位字,其中两个位是填充位,并且不用于存储部分值-即使类型为[-32767..32767]
,类型也只能存储<stdint.h>
大于16位。
[-32768..32767]
标头确实定义了具有特定的固定大小(16位,32位)的整数类型,但是它们可能并非在所有地方都可用。
class Product:
name = CharField(....)
size = CharField(....)
brand = CharField(....)
field4 = CharField(....)
class Meta:
unique_together = ("name","size","brand")
开始的原因。