2013-06-18 87 views
0

从这个FAQ:What are Aggregates and PODs and how/why are they special?吊舱和规则转到

我们有这样的一部分:

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; 
} 

我想了解为什么区别?它似乎可能是,即使POD是 goto后宣布它已经初始化,没有更多的需要做,而非POD未被初始化的 。还是我吠叫错了树?

回答

1

转到不能跳过初始化,除非它出现在一个块中,并且您跳过整个块。

对于non-POD,调用ctor。这是必要的,并且必须在变量出现的地方发生。如果你可以跳过它,那么这个变量就会被打破。最终它的计划将会爆炸。

+0

所以这意味着在POD情况下初始化已经完成,但在非POD的情况下,它还没有完成。 –

+0

POD不能有ctor - 这是要求之一,但我认为如果你使用{} init,也会失败。 –

+0

那么,构造函数是隐含的,它必须在某个点运行。 goto不能跳过初始化,所以POD必须已经初始化。我试图弄清楚什么时候会发生。 –

1

f的情况下,x析构函数(其由编译器自动在具有构造为由设置,从而使struct非POD型)将被称为“在返回”。对未构造的对象调用析构函数并不是一个好计划。如果我们让这个代码更复杂一些,那么我们很容易就会在编译器非常复杂的情况下知道哪些对象已经被初始化,哪些没有被初始化,所以只是简单地禁止跳过任何初始化(使用switch语句来,其中某些对象每种情况下内导入时的该另一个常见的情况是:

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

是一个类似的构建体(和同样不好)

+0

所以POD已经被初始化了,goto可以跳过它。 POD是什么时候初始化的? –