2011-12-16 10 views
6

私はC++標準を読んでいるとき、次のコードは標準に従って完全に問題ないと思われます。初期化子を使用せずにスカラー型のオブジェクトのスコープにジャンプするのはどうですか?

int main() { 
    goto lol; 
    { 
     int x; 
lol: 
     cout << x << endl; 
    } 
} 

// OK 

[n3290:6.7/3]:それはなく、初期化と宣言をバイパス ように、ブロックに転送することが可能です。 変数がスカラー型、自明なデフォルト コンストラクタとクラスタイプを持っていない限り は、それが範囲内にあるポイントへの自動保存期間を持つ変数がスコープ内 ない点からジャンププログラムは病気形成あります些細なデストラクタ、これらの型の のいずれかのcv修飾バージョン、または上記の型のいずれかの配列があり、のない と宣言されています。

なぜ機能するのですか?その定義を飛び越して、未定義のxを使用するのはまだ危険なのですか?そして、なぜ初期化子の存在が何か変わるべきなのでしょうか?

答えて

7

int x;はまだ初期化されていないため、いずれにしても初期化されていないxを使用します。あなたがそれをスキップするので、イニシャライザの存在はもちろん違いになります。例えばint x = 5;xを初期化するので、上にジャンプした場合とそうでない場合に違いがあります。

+0

しかし、問題は、初期化子があるにもかかわらず、xの定義がバイパスされているためです。ではない? –

+0

@EricZ:定義はまだ発生します。 'goto'は実行時のものですが、初期化のように実行時の動作のみをスキップします。 – GManNickG

+0

@Gman、右!ありがとう;) –

2

まだ定義を飛び越して初期化されていないxを使用するのは危険ですか?

しかし、xは初期化せずに宣言されているため、とにかく初期化されません。したがって、gotoは、(sort-of-initialize)xを設定する代入ステートメントをスキップすることがありますが、gotoが代入ステートメントをスキップできることは驚くことではありません。宣言自体は、イニシャライザがない限り、実際にはを実行しません。は何も行いません。

+1

+1 *宣言自体は実際に何もしません*。それが重要なポイントです。イニシャライザがなければ、コードは生成されません。このルールは、実際にコードをスキップしていないことを保証します。 –

+0

@Ernest、その定義が去ったのでxがどのように定義されているのか興味がありますか? –

+2

フリープロセッサレジスタが「x」を保持するように指定されているとします。これはコンパイラでの単なる簿記です。生成されたコードに物理的に「レジスタ17は現在xである」ということはありません。今、 'x'が初期化されていれば、レジスタの値を設定するコードがあります - しかし、言ったように、それはありません。 –

関連する問題