0

来自此常见问题解答:什么是聚合和 POD,它们如何/为什么特别?

我们有这部分:

goto 语句。您可能知道,通过 goto 从某个变量尚未在范围内的点跳转到它已经在范围内的点是非法的(编译器应该发出错误)。仅当变量为非 POD 类型时,此限制才适用。在以下示例中,f() 是非良构的,而 g() 是良构的。请注意,Microsoft 编译器对这条规则过于宽松 - 在这两种情况下都会发出警告。

int f() {
  struct NonPOD { NonPOD(){}};
  goto label;
  NonPOD x;
label:
  return 0;
}

int g(){
  struct POD {int i;  char c;};
  goto label;
  POD x;
label:
  return 0;
}

我想了解为什么会有差异?似乎可能是即使在 goto 之后声明了 POD,它也已经初始化并且不需要做任何其他事情,而非 POD 没有初始化。还是我在叫错树?

4

2 回答 2

1

Goto 不能跳过初始化,除非它出现在一个块中,并且你跳过了整个块。

对于非 POD,调用 ctor。这是必要的,并且必须发生在变量出现的地方。如果您可以跳过它,则可以在损坏状态下访问该变量。最终它的 dtor 会引爆这个程序。

于 2013-06-18T17:16:33.243 回答
1

在 的情况下f,析构函数x(由编译器基于具有构造函数而自动提供,从而使struct非 POD 类型)将被称为“返回时”。在尚未构造的对象上调用析构函数不是一个好计划。如果我们让这段代码足够复杂,我们很容易陷入这样一种情况,编译器很难知道哪些对象已经初始化,哪些没有,所以简单地禁止跳过任何初始化会更安全(另一个常见的情况是在使用switch-statement 时,在每种情况下都会引入一些对象:

switch(x)
{
   case 1:
      NonPod x;
      ..
      break;
   case 2: 
      ...
}

是一个类似的结构(同样糟糕)。

于 2013-06-18T17:22:43.590 回答