从此常见问题解答:What are Aggregates and PODs and how/why are they special?
我们有这一部分:
转到声明。您可能知道,从某个变量尚未在范围内的点到已经在范围内的点,通过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;
}
我想了解为何有区别?看起来即使POD是可能的 在goto之后声明它已经被初始化,没有什么需要做的了 非POD未初始化。还是我在错误的树上吠叫?
答案 0 :(得分:1)
Goto无法跳过初始化,除非它出现在一个块中,并跳过整个块。
对于非POD,调用ctor。这是必要的,必须在变量出现的地方发生。如果你可以跳过它,那么变量将以破坏状态访问。最终它的dtor会爆炸该程序。
答案 1 :(得分:1)
在f
的情况下,x
的析构函数(由编译器根据构造函数自动提供,从而使struct
成为非POD类型)将被称为“返回”。在未构造的对象上调用析构函数不是一个好计划。如果我们使这段代码变得更加复杂,我们可以很容易地在编译器知道哪些对象已经被初始化而哪些没有被初始化的情况下非常复杂,因此仅仅禁止跳过任何初始化更安全(另一个常见的情况是使用switch
- 语句,其中在每种情况下引入了一些对象:
switch(x)
{
case 1:
NonPod x;
..
break;
case 2:
...
}
是一个类似的结构(同样糟糕)。