C++におけるgoto文について

これはAmusementCreators AdventCalendar14日の記事です。

C++にはC言語と違ってclassがあるため結構複雑になってる。

goto文が変数の宣言を飛び越える時

危険だし全く推奨されないのだけどgoto文で変数宣言を飛び越えることができる。 つまり以下は合法。

    goto some_label;
    int value;
some_label :

しかしこのようにgoto文で飛び越えれる自動ストレージ*1上の変数には以下のいずれかを満たさなければならない。

  • スカラー型である
  • trivialでdefaultなコンストラクタとtrivialなデストラクタを持つ
  • これらの型がCV修飾された型
  • これらの型の配列型

さらに

  • 初期化子なしで宣言されなければならない

という制限もある。

例を示すと

    goto some_label;
    int x;              // いい
    int x = 0;          // 悪い(初期化子がある)
    Pod obj1;           // いい
    NonPod obj2;        // 悪い(trivialでない)
    static NonPod obj3; // 良い(そもそも自動ストレージに確保されない)
    static NonPod obj4{};  // 良い(初期化子があっても上と同じ理由で)
some_label :

goto文で処理が巻き戻るとき

このような時は宣言を跨がれた変数は破棄される。当然デストラクタも呼ばれる。

some_label :
    SomeClass object;
    goto some_label; // ここでobjectが破棄される

まとめ

そもそもイディオム化した書き方以外でgoto文を使うのはやめよう。

*1:ぶっちゃけスタック領域の事だが規格上はコンパイラはスタック領域として実装する必要はない