TL;博士
该行为是有效的,并且确实存在这样的编译器/架构
- TI C5500/C6000 带 4 字节
int
、5 字节long
- 摩托罗拉 DSP5600x/3xx 系列带 2 字节
short
、3 字节int
、6 字节long
- x86 8-byte
double
, 10-bytelong 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 整数类型的大小 <limits.h>
- 下面给出的值应替换为适用于
#if
预处理指令的常量表达式。此外,除了CHAR_BIT
and之外MB_LEN_MAX
,以下内容应替换为与作为根据整数提升转换的相应类型的对象的表达式具有相同类型的表达式。它们的实现定义值的大小(绝对值)应等于或大于所示值,符号相同。[...]
6.2.5 类型
有五种标准有符号整数类型,分别指定为signed char
、short int
、int
、long int
和long long int
。(这些和其他类型可以用几种额外的方式指定,如 6.7.2 中所述。)也可能存在实现定义的扩展有符号整数类型。28)
标准和扩展的有符号整数类型统称为有符号整数类型。29)
对于任何两个具有相同符号和不同整数转换等级的整数类型(见 6.3.1.1),具有较小整数转换等级的类型的值范围是另一个类型的值的子范围。
奇数大小的整数类型要少得多,但仍然存在。许多 DSP 具有符合标准的编译器,具有32 位和40 位的非幂或 2 类型。int
long
long
是
- C6000 COFF 为 40 位或 5 个字节。这完全符合任何主要的 C/C++ 标准,因为这些标准都为 long (aka. long int) 定义了 4 字节的最低要求。程序员经常错误地假设这种类型的大小正好是 4 个字节。
强调我
在 TI 编译器中对 C89 的支持#对 TI C 的误解
越位说明:在某些 TI 目标上,甚至long long
也是 32 位或 40 位类型,这在 C89 中作为扩展有效,但违反 C99
一些目标有long long
(C99 的扩展),但不是符合标准的。C99 至少需要 64 位,但 C2700 有 32-bit long long
,而 C5500 有 40-bit long long
。C2800、C6000、ARM有64位long long
,C5400、MSP430不支持long long
。这在技术上并不违反 C89,因为这实际上是一个扩展,但如果我们开始支持 C99,这将违反 C99(C99 5.2.4.2.1“整数类型的大小 <limits.h>”第 1 段)。
更宽类型的大小甚至不必是其前一个类型大小的倍数。继续Derek M. Jones 在新 C 标准(摘录材料)中所说的话:经济和文化评论
...例如,德州仪器公司的 TMS320C6000,一个 DSP 处理器,使用 32 位表示类型int
,使用 40 位表示类型long
(这种选择并不少见)。那些使用 24 位来表示类型的处理器(通常是 DSP)int
,往往使用 48 位来表示类型long
。24/48 位整数类型表示的使用可以由 32/64 位整数类型表示不具成本效益的应用需求驱动。
在我之前知道的所有 24 位 DSP 中,CHAR_BIT == 24
所有类型的大小都是 24 位的倍数,但我刚刚发现摩托罗拉 DSP5600x/3xx 系列有一个非常“奇怪”的类型系统
数据类型 |
位大小 |
(无符号的字符 |
8 |
(un)signed short |
16 |
(un)signed int |
24 |
(un)signed long |
48 |
(长)_fract |
24 (48) |
指针 |
16/24 |
浮动/双 |
24+8 |
枚举 |
24 |
所以在这种情况下sizeof(char) == 1
and sizeof(short) == 2
but sizeof(int) == 3
andsizeof(long) == 6
不幸的是,GCC 称它们为 ( long
and long long
)双字整数,大多数人也是如此,这造成了很大的误解,尽管它不一定是两倍大小。