C ++ 03
$ 5.3.3 / 2 - “大多数派生的 class应大于零 (1.8)。“
$ 1.8 / 4 - “除非它是一个小字段 (9.6),最衍生的对象 具有非零大小并且应占用 一个或多个存储字节。“
我的问题是:
是否未指定空类的大小,实现是否已定义?是否应该由编译器文档记录?就我的理解是正确的而言,这两个引语让它如此开放。
答案 0 :(得分:4)
未指定(除非必须大于0)。它也不是实现定义的(因此不需要记录)。
我不确定为什么实现会为空类使用除1以外的任何大小(假设通过“空类”我们讨论的是一个甚至不从另一个类派生的类),但我想它可以。
解决Chubsdad关于什么决定这是未指明行为的问题(与实施定义相反):
标准将“未指明的行为”定义为:
行为,对于格式良好的程序构造和正确的数据,取决于实现。该 不需要实现来记录发生的行为。
它将“实现定义的行为”定义为:
行为,对于格式良好的程序构造和正确的数据,取决于实现和 每个实施应记录
因此,两者之间的唯一区别是必须记录实现定义的行为。该标准将说明何时必须记录行为(通常通过说行为是实现定义的)
不幸的是,标准并不总是直接声明行为未指定(或未定义)。所以,有些分析是有序的:
由于标准说:
sizeof
必须为空类评估大于零的结果,通过消除过程,未指定空类的大小。
这种分析可能存在的问题(以及对C ++标准这么复杂的事情进行了大量分析)是,我可能会错过标准的另一个角落,可能需要空类的大小为一些具体的价值。那个要求可能是通过其他一些规则推断(或者是否会被推论?);它可能没有完全说明。追踪可能适用于特定问题的标准的所有领域并不总是容易的。
如果是这样的话,那么有人会希望注意到这一点,然后向下开枪。
答案 1 :(得分:1)
大多数派生类型是指类类型的完整对象的类(C ++标准的1.8(intro.object))。因此,实例化的空类必须具有唯一的地址,这意味着sizeof(empty class)>0
。但是,这也意味着您可以拥有零大小的基类(也是1.8的C ++标准)。
因此,如果必须实例化一个空类,则其大小不能为零。如果它是基类子对象,那么它的大小可以为零。