每个 C 数据类型的大小都保证是字节的整数倍吗?

Cor*_*250 2 c c89 c11

我知道 sizeof(char) 将始终为 1,并且这是以字节为单位的,并且一个字节可以是任意数量的位(我相信大于或等于 8 的任意数量的位,但不是正数) )。

我还经常看到提到如何根据 C 数据类型大小之间的关系来指定 C 数据类型大小的参考资料,例如“sizeof(int) <= sizeof(long)”。

我的问题基本上是:在一个字节为 8 位、一个 int 为 39 位(或其他不能被 CHAR_BIT 整除的值)的系统上,“sizeof(int)”的计算结果是什么。

我的猜测是 sizeof() 返回存储类型所需的最小字节数,因此它会向上舍入到下一个字节。因此,在我的 39 位 int 示例中,sizeof(int) 的结果将为 5。

它是否正确?

另外,是否有一种简单的方法来确定特定类型可以容纳的位数,该方法是 100% 可移植的并且不需要包含任何标头?这更多的是一种学习体验,而不是实际应用。我在实践中只使用 stdint 类型。我在想也许是声明变量并将其初始化为~0,然后循环并左移直到它为零。

谢谢!

use*_*438 6

人们常常无法理解的是,在 C 语言中,“宽度”和“宽度”之间有明显的区别sizeof

“宽度”更多的是关于二进制表示、范围、溢出/环绕行为。你说无符号整数类型是 16 位宽,那么你的意思是它在 65535 处环绕。

然而sizeof只关心存储。因此通过允许包含填充来sizeof(T[n])==sizeof(T)*n维持。sizeof

因此,试图找到sizeof类型和类型的算术行为之间的联系是没有意义的:类型可以具有一定的范围,但可以占用它想要的任何存储空间。

为了回答你的问题(“如果8位字符机器上的39位int怎么办?”)我想使用TI C6400+作为示例,因为它有40位long和8位字符,非常关闭。

TI C6400+ 是字节可寻址机器,因此它必须将 8 位字节定义为char.

它还具有 40 位整数类型,因为 ALU 可以对 40 位整数进行操作,并且他们将其定义为long.

你可能认为sizeof(long)应该是5,对吗?

嗯,可以,但是这个 CPU 也不能很好地支持未对齐加载,因此出于性能原因,这种long类型默认对齐到 8 字节边界而不是 5 字节,然后每个long都有 3 字节的填充(在两个内存中)和寄存器级别,因为它也需要CPU中的一对GPR),那么自然sizeof(long)就变成8。

有趣的是,C6400+ C 实现也提供了long long8sizeof(long long)位。但这是真正的 64 位宽类型,并且具有完整的 64 位范围而不是 40 位。

更新

回到“39 位”的情况。

由于6.2.8.1要求所有完整类型的对齐方式是“字节”的整数倍,因此如果是CHAR_BIT8,则39位整数必须填充到至少40位或更大,因此sizeof这样的类型必须是大于或等于5。