像int
这样的原始数据类型的大小究竟取决于什么?
或者是这些因素还是其他因素的组合? 对其原因的解释将非常有用。
编辑:很抱歉混淆..我想询问关于原始数据类型如int而不是关于POD,我确实理解POD可以包括结构和结构它是一个完整的不同的球游戏与填充进入图片。 我已经更正了Q,这里的编辑说明应该确保关于POD的答案看起来不相关。答案 0 :(得分:8)
我认为这个问题有两个部分:
允许原始类型的大小。
这个is specified by the C and C++ standards:类型允许它们必须具有的最小值范围,它隐含地将它们的大小的下限设置为(例如long
必须至少为32位符合标准)
标准没有指定大小(以字节为单位),因为definition of the byte取决于实现,例如char
是字节,但字节大小(CHAR_BIT
宏)可能是16位。
实施所定义的实际尺寸
正如其他答案已经指出的那样,这取决于实现:编译器。反过来,编译器实现受目标体系结构的严重影响。因此,让两个编译器在相同的操作系统和体系结构上运行,但具有不同的int
大小是合理的。您可以做出的唯一假设是标准规定的假设(假设编译器实现它)
还可能有其他ABI要求(例如固定的枚举大小)。
答案 1 :(得分:6)
首先,它取决于编译器。编译器通常依赖于体系结构,处理器,开发环境等,因为它将它们考虑在内。所以你可能会说它是所有的组合。 但我不会这么说。我会说,编译器,因为如果你使用不同的编译器,因为在同一台机器上你可能有不同大小的POD和内置类型。另请注意,您的源代码是输入到编译器的,因此编译器使得最终决定POD和内置类型的大小。但是,这一决定也受到目标机器底层架构的影响。毕竟,真正的 有用的 编译器必须发出高效的代码,这些代码最终会在您定位的计算机上运行。< / p>
编译器也提供options
。其中很少可能影响尺寸!
char
,signed char
和unsigned char
的大小由C ++标准本身定义!所有其他类型的大小由编译器定义。
C ++ 03标准$ 5.3.3 / 1说,
sizeof(char),sizeof(signed char)和 sizeof(unsigned char)是1;该 sizeof应用于任何其他的结果 基本类型(3.9.1)是 实现定义。 [注意:在 特别是,sizeof(bool)和 sizeof(wchar_t)是 实施-defined.69)
C99标准($ 6.5.3.4)本身也将char
,signed char
和unsigned char
的大小定义为1,但保留编译器定义的其他类型的大小!
编辑:
我发现这个C ++ FAQ章节非常好。整章。这是一个非常小的篇章。 : - )
http://www.parashift.com/c++-faq-lite/intrinsic-types.html
另外阅读下面的评论,有一些好的论点!
答案 2 :(得分:2)
如果你问的是像int
这样的原语类型的大小,我会说这取决于你引用的因素。
编译器/环境耦合(环境通常意味着操作系统)肯定是其中的一部分,因为编译器可以出于各种原因以不同的方式映射内置类型上的各种“敏感”大小:例如,x86_64上的编译器Windows通常会有一个32位long
和一个64位long long
,以避免破坏普通x86的代码;相反,在x86_64 Linux上,long
通常是64位,因为它是一个更“自然”的选择,为Linux开发的应用程序通常更加架构中立(因为Linux运行在更多种类的架构上)。
处理器肯定在决定中很重要:int
应该是处理器的“自然大小”,通常是处理器的通用寄存器的大小。这意味着它是在当前架构上工作得更快的类型。 long
通常被认为是一种在扩展范围内交换性能的类型(在普通PC上很少见,但在微控制器上这是正常的)。
如果您正在谈论struct
s&amp;合。 (如果他们尊重某些规则,是 POD
),编译器和处理器会再次影响它们的大小,因为它们是由内置类型和编译器选择的适当填充构成的在目标架构上实现最佳性能。
答案 3 :(得分:2)
正如我在@ Nawaz的答案中评论的那样,它在技术上完全取决于编译器。
编译器的任务是获取有效的C ++代码,并输出有效的机器代码(或其目标语言)。
因此,C ++编译器可以决定使int
的大小为15,并要求它在5字节边界上对齐,而可以> em>决定在POD中的变量之间插入任意填充。标准中没有任何内容禁止这样做,它仍然可以生成工作代码。
它会慢很多。
所以在实践中,编译器会从两个运行的系统中获取一些提示:
- CPU具有某些偏好:例如,它可能具有32位宽的寄存器,因此使int
32位宽是一个好主意,它通常需要变量自然对齐(4字节)例如,宽变量必须在可被4整除的地址上对齐,因此敏感的编译器会尊重这些首选项,因为它会产生更快的代码。
- 操作系统也可能有一些影响,因为如果它使用另一个ABI而不是编译器,那么系统调用就会变得不必要了。
但这些只是让程序员生活更轻松或生成更快代码的实际考虑因素。他们不是必需的。
编译器有最后一个字,可以选择完全忽略CPU和OS。只要它使用C ++标准中指定的语义生成工作可执行文件。
答案 4 :(得分:0)
这取决于实现(编译器)。
Implementation-defined behavior
表示未指定的行为,其中每个实现记录了如何做出选择。
答案 5 :(得分:0)
struct
也可以是POD,在这种情况下,您可以在某些编译器上明确控制#pragma pack
成员之间的潜在填充。