3字节int和5字节长?

每个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是一种有效的行为?

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

我认为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位才能满足范围要求。 否则,除上述情况外,我们没有任何特定的尺寸限制。

TL; DR

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

  • TI C5500 / C6000具有4字节int ,5字节long
  • Motorola 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_BITMB_LEN_MAX ,以下内容应替换为与根据整数提升转换的对应类型的对象的表达式具有相同类型的表达式。 它们的实现定义值的大小(绝对值)应等于或大于显示的值,具有相同的符号。 […]

6.2.5类型

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

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


奇数大小的整数类型更为罕见,但仍然存在。 许多DSP都有符合标准的编译器, 非幂或2类型 ,其中int有32位, long40位

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位,C5500的long long 40位。 C2800,C6000和ARM的long long 64位,而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位表示int类型的处理器(通常是DSP)通常使用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 

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

不幸的是,GCC将它们称为( longlong long ) 双字整数 ,大多数人都这样称呼它们,造成很大的误解,尽管它不一定是规模的两倍。

C ++标准(几乎可以肯定是C标准,但我很长时间没有看过它)没有规则说明类型应该是多少位数。 我知道允许9位char的事实,并且有36位整数的机器。 我上次检查时,9或36都不是2的幂。

绝对有24位整数的平台。 今天仍然在某些嵌入式应用程序中使用它。 您可以查看维基百科以获取更多信息: http : //en.wikipedia.org/wiki/24-bit