2

C++03

$5.3.3/2 - “最大派生类的大小应大于零 (1.8)。”

$1.8/4 - “除非它是位字段 (9.6),否则最派生的对象应具有非零大小并应占用一个或多个字节的存储空间。”

那么我的问题是:

空类的大小是否未指定,实现是否已定义?它应该由编译器文档记录吗?据我的理解是正确的,这两个引用让它如此开放。

4

2 回答 2

4

它是未指定的(除了它必须大于 0)。它也不是实现定义的(因此不需要记录)。

我不确定为什么一个实现会为一个空类使用除 1 之外的任何大小(假设“空类”我们正在谈论一个甚至不是从另一个类派生的类),但我想它可以。


为了解决 Chubsdad 关于什么决定这是未指定的行为(与定义的实现相反)的问题:

该标准将“未指定行为”定义为:

行为,对于格式良好的程序构造和正确的数据,这取决于实现。实现不需要记录发生了哪些行为。

它将“实现定义的行为”定义为:

行为,对于格式良好的程序构造和正确的数据,这取决于实现并且每个实现都应记录

因此,两者之间的唯一区别是必须记录实现定义的行为。该标准将说明何时必须记录行为(通常是说行为是实现定义的)

不幸的是,该标准并不总是直接声明行为未指定(或未定义)。因此,一些分析是有序的:

由于标准说:

  • 对于空类,它sizeof必须评估为大于零的结果,
  • 没有说明该值必须是什么(大于零除外)
  • 没有说必须记录该值(或者它是实现定义的)

通过消除过程,未指定空类的大小。

这种分析(以及对像 C++ 标准一样复杂的东西的大量分析)可能存在的问题是,有可能我错过了标准的其他一些角落,这可能需要空类的大小是某个特定值. 并且该要求可能是从其他一些规则中推断出来的(或者是推论?);可能不会直接说明。追踪标准中可能适用于特定问题的所有领域并不总是那么容易。

如果是这样的话,那么希望有人会注意到这一点并驳回我的论点。

于 2010-12-04T00:33:58.020 回答
1

大多数派生类型是指类类型的完整对象的类(C++ 标准的 1.8 (intro.object))。所以实例化的空类必须有一个唯一的地址,这意味着sizeof(empty class)>0. 但是,这也意味着您可以拥有一个大小为零的基类(也在 C++ 标准的 1.8 中)。

因此,如果您必须实例化一个空类,它的大小不能为零。如果它是基类子对象,那么它的大小可以为零。

于 2010-12-04T00:40:11.030 回答