未定义,实现定义,未指定的行为

时间:2010-12-04 00:25:23

标签: c++ unspecified-behavior

C ++ 03

  

$ 5.3.3 / 2 - “大多数派生的   class应大于零   (1.8)。“

     

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

我的问题是:

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

2 个答案:

答案 0 :(得分:4)

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

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


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

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

  

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

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

  

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

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

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

由于标准说:

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

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

这种分析可能存在的问题(以及对C ++标准这么复杂的事情进行了大量分析)是,我可能会错过标准的另一个角落,可能需要空类的大小为一些具体的价值。那个要求可能是通过其他一些规则推断(或者是否会被推论?);它可能没有完全说明。追踪可能适用于特定问题的标准的所有领域并不总是容易的。

如果是这样的话,那么有人会希望注意到这一点,然后向下开枪。

答案 1 :(得分:1)

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

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