3字节int和5字节长?

sas*_*hka 13 c c++ sizeof

每个C和C++标准是否允许sizeof数字类型不是 2的幂?

已知以下约束:

  • 16 <= CHAR_BIT * sizeof(int) <= CHAR_BIT * sizeof(long)
  • 32 <= CHAR_BIT * sizeof(long) <= CHAR_BIT * sizeof(long long)
  • 和其他十几个,在典型的8位字节架构上意味着 2 <= sizeof(int) && 4 <= sizeof(long)

这是否意味着这sizeof(int) == 3 && sizeof(long) == 5是一种有效的行为?

如果是 - 是否有任何已知的编译器/架构以类似的方式运行?

Mar*_*k B 12

我认为3.9.1/2(C++ 98)很好地总结了这一点(紧接着是无符号类型的类似信息):

有四种带符号的整数类型:"signed char","short int","int"和"long int".在此列表中,每种类型至少提供与列表中前面的存储一样多的存储空间.简单的int具有执行环境的体系结构所建议的自然大小39); 提供其他有符号整数类型以满足特殊需求.

基本上我们所知道的是,sizeof(char) == 1每个"更大"的类型至少是那么大,int对于一个架构来说是一个"自然"大小(据我所知,"自然"取决于编译器编写者).我们不知道类似的东西CHAR_BIT * sizeof(int) <= 32.还要记住,CHAR_BIT也不必是8.

对于那些本地使用这些大小的硬件来说,允许使用三个字节int和五个字节似乎是相当安全的long.但是我不知道任何这样的硬件/架构.

编辑:正如在@Nigel Harper评论中指出的那样,我们知道int必须至少有16位且long至少32位才能满足范围要求.否则,除上述情况外,我们没有任何特定的尺寸限制.

  • 一些Unisys大型机有`sizeof(int)== 6`(其他的有`CHAR_BIT == 9`).(旧的CDC大型机有60位字; C实现可能有`CHAR_BIT == 10`和`sizeof(int)== 6`.但我不认为它们有任何C编译器,很多减少C++;它在20世纪70年代的某个时候就已经停产了.) (5认同)

phu*_*clv 6

TL; DR

行为是有效的,并且存在这样的编译器/体系结构

  • TI C5500/C6000具有4字节int,5字节long
  • 摩托罗拉DSP5600x/3xx系列具有2字节short,3字节int,6字节long
  • x86具有8字节double,10字节long double

用于表示类型的位数long并不总是与类型中的位数相同,或者是该位数的整数倍int.可能需要表示更大范围的值(比int类型更可能)的能力,但处理器成本也可能是一个考虑因素......

Derek M. Jones的新C标准(摘录材料) - 经济和文化评论


另一个答案已经回顾了C++标准要求.类似地,C标准也没有将字节的类型(浮点或整数)大小限制为2的幂.最常见的例子是long double,在x86中最常见的是10个字节(在许多现代中填充为12或16个字节)编译器).

ISO/IEC 9899:1999(E)

5.2.4.2.1整数类型的大小

  1. 下面给出的值应替换为适用于#if预处理指令的常量表达式.此外,除了CHAR_BIT和之外MB_LEN_MAX,以下内容应由与表达式相同的表达式替换,该表达式是根据整数提升转换的相应类型的对象.它们的实现定义值的大小(绝对值)应等于或大于显示的值,并带有相同的符号.[...]

6.2.5类型

  1. 有五种标准符号整数类型,指定为signed char,short int,int,long int,和long long int.(这些和其他类型可以用几种其他方式指定,如6.7.2中所述.)也可能存在实现定义的扩展有符号整数类型.28)
    标准和扩展有符号整数类型统称为有符号整数类型.29)

  2. 对于具有相同签名和不同整数转换等级的任何两个整数类型(参见6.3.1.1),具有较小整数转换等级的类型的值范围是另一种类型的值的子范围.


奇数大小的整数类型更为罕见,但仍然存在.许多DSP具有符合标准的编译器,具有非功率或2类型,其中int32位,long具有40位.

long

  • C6000 COFF为40位或5字节.这完全符合任何主要的C/C++标准,因为这些标准都定义了长度为4字节的最低要求(aka.long int).程序员经常错误地认为这种类型的大小正好是4个字节.

重点关注
TI编译器中的C89支持#关于TI C的误解

越位注意:在一些TI目标上,甚至long long也是32位或40位类型,在C89中作为扩展有效但违反了C99

有些目标long long(来自C99的扩展),但不是符合要求的目标.C99至少需要64位,但C2700需要32位long long,而C5500需要40位long long.C2800,C6000和ARM具有64位long long,而C5400和MSP430不支持long long.这在技术上并不违反C89,因为这实际上是一个扩展,但如果我们开始支持C99,这将违反C99(C99 5.2.4.2.1"整数类型的大小"第1段).

更宽的类型的大小甚至不必是其先前类型的大小的倍数.继续Derek M. Jones在新C标准(摘录材料)中所说的:经济和文化评论

...例如,德州仪器(TI)TMS320C6000是一个DSP处理器,使用32位表示类型int,40位表示类型long(这种选择并不少见).使用24位表示类型的那些处理器(通常是DSP)int通常使用48位来表示类型long.24/48位整数类型表示的使用可以由应用程序要求驱动,其中32/64位整数类型表示不具有成本效益.

在我以前所知的所有24位DSP中,CHAR_BIT == 24所有类型的大小都是24位的倍数,但我发现摩托罗拉DSP5600x/3xx系列有一个非常"奇怪"的类型系统

Data Type           size in bits
(un)signed char     8
(un)signed short    16
(un)signed int      24
(un)signed long     48
(long)_fract        24 (48)
pointer             16/24
float/double        24+8
enum                24
Run Code Online (Sandbox Code Playgroud)

所以在这种情况下sizeof(char) == 1,sizeof(short) == 2但是sizeof(int) == 3sizeof(long) == 6

不幸的是,GCC称他们为(longlong long)双字整数,大多数人也是如此,这是一个很大的误解,尽管它不一定是双倍的大小.