原始数据类型的大小

关于像int这样的原始数据类型的大小究竟取决于什么?

  • 编译器
  • 处理器
  • 发展环境

或者它是这些或其他因素的组合?
对其原因的解释将非常有帮助。

编辑:对不起混淆..我想询问有关原始数据类型如int而不是关于POD,我确实理解POD可以包括结构和结构它是一个完整的不同的球游戏与填充进入图片。 我已经更正了Q,这里的编辑说明应该确保关于POD的答案看起来不相关。

我认为这个问题有两个部分:

  1. 允许原始类型的大小。
    这由C和C ++标准规定 :类型允许它们必须具有的最小值范围,其隐含地以位为单位设置其大小的下限(例如, long必须至少为32位以符合标准)。
    标准没有指定字节大小,因为字节的定义取决于实现,例如char是字节,但字节大小( CHAR_BIT宏)可能是16位。

  2. 实现定义的实际大小。
    正如其他答案已经指出的那样,这取决于实现:编译器。 反过来,编译器实现受目标体系结构的严重影响。 因此,有两个编译器在相同的操作系统和体系结构上运行,但具有不同的int大小是合理的。 您可以做的唯一假设是标准规定的假设(假设编译器实现它)。
    还可能存在额外的ABI要求(例如,固定的枚举大小)。

首先,它取决于编译器。 编译器通常依赖于体系结构,处理器,开发环境等,因为它将它们考虑在内。 所以你可能会说它是所有的组合。 但我不会这么说。 我会说,编译器 ,因为在同一台机器上你可能有不同大小的POD和内置类型,如果你使用不同的编译器。 另请注意,您的源代码是输入到编译器的,因此编译器最终决定了POD和内置类型的大小。 但是,这个决定也受到目标机器底层架构的影响。 毕竟,真正有用的编译器必须发出最终在您定位的机器上运行的高效代码。

编译器也提供了options 。 其中很少可能影响尺寸!


编辑:标准说什么,

charsigned charunsigned char大小由C ++ Standard本身定义! 所有其他类型的大小由编译器定义。

C ++ 03标准$ 5.3.3 / 1说,

sizeof(char),sizeof(signed char)和sizeof(unsigned char)是1; sizeof应用于任何其他基本类型(3.9.1)的结果是实现定义的。 [注意:特别是sizeof(bool)和sizeof(wchar_t)是实现定义的.69)

C99标准($ 6.5.3.4)本身也将charsigned charunsigned char的大小定义为1,但保留编译器定义的其他类型的大小!


编辑:

我发现这个C ++ FAQ章节非常好。 整章。 这是非常小的篇章。 🙂

http://www.parashift.com/c++-faq-lite/intrinsic-types.html


另外阅读下面的评论,有一些很好的论点!

如果你问的是像int这样的原始类型的大小,我会说它取决于你引用的因素。

编译器/环境耦合(环境通常意味着操作系统)肯定是其中的一部分,因为编译器可以出于各种原因以不同方式映射内置类型上的各种“敏感”大小:例如,x86_64 Windows上的编译器通常会有一个32位long ,64位long long以避免破坏普通x86的代码; 相反,在x86_64 Linux上, long通常是64位,因为它是一个更“自然”的选择,为Linux开发的应用程序通常更加架构中立(因为Linux运行在更多种类的架构上)。

处理器肯定很重要: int应该是处理器的“自然大小”,通常是处理器的通用寄存器的大小。 这意味着它是在当前架构上工作得更快的类型。 相反,通常被认为是一种在扩展范围内交易性能的类型(在常规PC上很少见,但在微控制器上这是正常的)。

如果相反,你也在谈论struct s&co。 (如果它们遵守某些规则, 则是 POD ),编译器和处理器再次影响它们的大小,因为它们由内置类型和编译器选择的适当填充构成,以在目标体系结构上实现最佳性能。

正如我在@ Nawaz的回答中评论的那样,它在技术上完全取决于编译器。

编译器的任务是获取有效的C ++代码,并输出有效的机器代码(或其目标语言)。

因此,C ++编译器可以决定使int的大小为15,并要求它在5字节边界上对齐,并且它可以决定在POD中的变量之间插入任意填充。 标准中没有任何内容禁止这样做,它仍然可以生成工作代码。

它会慢得多。

所以在实践中,编译器从它们运行的​​系统中获取一些提示,有两种方式: – CPU有一定的偏好:例如,它可能有32位宽的寄存器,所以制作一个32位宽的int将是一个好主意,它通常要求变量自然对齐(例如,一个4字节宽的变量必须在可被4整除的地址上对齐),因此合理的编译器会尊重这些偏好,因为它会产生更快的代码。 – 操作系统也可能有一些影响,因为如果它使用另一个ABI而不是编译器,那么系统调用就会变得不必要了。

但这些只是让程序员更容易生活或生成更快代码的实际考虑因素。 他们不是必需的

编译器有最后一个字,它可以选择完全忽略CPU和OS。 只要它使用C ++标准中指定的语义生成工作可执行文件。

这取决于实现(编译器)。

Implementation-defined behavior意味着未指定的行为,其中每个实现都记录了如何进行选择。

struct也可以是POD,在这种情况下,您可以在某些编译器上使用#pragma pack明确控制成员之间的潜在填充。