为什么数据类型的大小会随着操作系统的变化而变化?

问题描述 投票:5回答:3

[在采访中问我这个问题,在某些操作系统中,char的大小为2字节,但是在某些操作系统中,其为4字节或不同。

为什么会这样?

为什么与其他基本类型(例如int)不同?

c++ c operating-system size
3个回答
9
投票

这可能是一个技巧问题。 sizeof(char)总是 1。

如果大小不同,可能是由于编译器不合格,在这种情况下,问题应该是关于编译器本身,而不是关于C或C ++语言。

5.3.3 Sizeof [expr.sizeof]

1 sizeof运算符得出对象中的字节数 其操作数的表示形式。操作数可以是一个表达式, 未评估的值,或带括号的type-id。的大小 运算符不得应用于具有功能或 不完整类型,或在所有其枚举数之前变为枚举类型 已声明,或以此类括号的名称,或 指定位字段的左值。 sizeof(char)sizeof(signed char)sizeof(unsigned char)为1。将sizeof应用于任何其他基本类型(3.9.1)的结果为 实现定义的。(重点是我的]

所指出类型以外的其他类型的大小是实现定义的,并且由于各种原因而有所不同。如果int用64位而不是32位表示,则具有更好的范围,但在32位体系结构上,它以32位表示的效率更高。


5
投票

类型的物理大小(以位数为单位)通常由目标硬件决定。

例如,某些CPU只能以不小于16位的单位访问内存。为了获得最佳性能,可以将char定义为16位整数。如果要在此CPU上使用8位字符,则编译器必须生成额外的代码,以便将8位值打包和拆包到16位存储单元中。多余的打包/解压缩代码会使您的代码变大和变慢。

这还没有结束。如果将16位存储单元细分为8位字符,则可以有效地在地址/指针中引入额外的位。如果CPU中的普通地址是16位,那么您将多余的第17位放在哪里?有两个选项:

  • 使指针变大(32位,其中有15个未使用),浪费了内存并进一步降低了速度
  • 将可寻址地址空间的范围减少一半,浪费内存,并失去速度

后一种选择有时可能很实用。例如,如果整个地址空间分成两半,其中一个由内核使用,另一半由用户应用程序使用,则应用程序指针将永远不会在其地址中使用一位。您可以使用该位在16位存储单元中选择8位字节。

C旨在在尽可能多的不同CPU上运行。这就是为什么charshortintlonglong longvoid*void(*)()floatdoublelong doublewchar_t的物理尺寸的原因,等等可能有所不同。

现在,当我们在讨论为同一CPU生成代码的不同编译器中的不同物理尺寸时,这将成为更多选择。但是,它可能看起来并不那么随意。例如,许多Windows编译器都定义int =long= 32位。他们这样做是为了避免程序员在使用Windows API时感到困惑,因为Windows API期望INT =LONG= 32位。由于缺少程序员的注意力,将intlong定义为其他名称会导致bug。因此,在这种情况下,编译器必须紧随其后。

最后,C(和C ++)标准与charsbytes一起使用。它们在大小上是相同的概念。但是C的字节不是您通常的8位字节,从法律上讲,它们可以比前面解释的大。为避免混淆,可以使用术语octet,其名称表示数字8。为此,许多协议都使用该词。


0
投票

感谢Alexey Frunze,这是我正在寻找的答案。我在安德鲁·tenenbawn操作系统书的硕士期间研究了这个概念]

© www.soinside.com 2019 - 2024. All rights reserved.