1

これはコードです:

#include <iostream>

void f() {
    throw 1;
    std::cout << "f(): should not be printed!!\n";
    std::cout << "f(): not should this!!\n";
}

int main(int, const char**) {
    f();
    std::cout << "main(): This not be printed!!\n";
    return 0;
}

コンソール アプリケーションとしてデバッグ モードで実行すると、デバッガーの下でスタックの巻き戻しがなく、cout ステートメントが出力されますか?

4

2 に答える 2

4

デバッガーで実行する場合、これは技術的に可能です。しかし、あなたはすべての話をしませんでした。例外がスローされると、デバッガーは最初にダイアログを表示します。これは次のようになります (私の場合は Windows 8 の VS2012 です)。

ここに画像の説明を入力

[Break] ボタンをクリックすると、デバッガーが throw ステートメントで中断し、状態を調べる機会が与えられます。[続行] ボタンをクリックすると、例外は無視され、プログラムは何も起こらなかったかのように続行します。これは、中断してから実行を再開したときにも発生します。

これは機能であり、バグではありません。これにより、すでに多くの時間を費やしたデバッグ セッションをレスキューできます。もちろん、プログラムが悪い状態にある可能性が高いため、続行することはあまり役に立ちませんが、代替手段も優れていません。ほとんどの場合、[中断] をクリックしてデバッガーを使用して状態を修正し、意味のあるデバッグを続行できるようにすることをお勧めします。

もちろん、これはデバッガーなしでは決して起こりません。プログラムは即座に終了します。

スタックの巻き戻しが発生する唯一の方法は、例外をキャッチするcatch句を記述することです。デバッグしているかどうかに関係なく。

于 2013-03-02T01:22:54.413 に答える
1

私自身の質問に答える鍵は、別のサブ質問に答えることにあります。例外がスローされた直後に、スタックの巻き戻しはどの時点から始まりますか?スタックの巻き戻しとは、逆の順序で、まだ存在するすべての自動オブジェクトのデストラクタを呼び出すことを意味します。回答:制御が例外ハンドラーに渡された時点で、つまり例外がキャッチされます。例外がキャッチされない場合、C ++例外メカニズムは、terminate関数が呼び出されるように指示し、これはデフォルトでabort()を呼び出します。このメカニズムは、次のコードで実際に動作していることがわかります。

struct X {
    ~X() { std::cout << "~X !!\n"; }
};

int main(int, const char**) {
    X x; 
    throw 1;
    return 0;
}

スロー後、例外ハンドラーが制御を取得していないため、プログラムが異常終了するため、Xのデストラクタが呼び出されることはありません。最初の質問に戻ると、デバッグビルドをデバッグしているときに、プログラムの実行中に適切なtry-catchブロックがない場合に例外がスローされると、MSStudioデバッガーはスローポイントで中断して表示されます。上記のダイアログウィンドウが表示され、「続行」するオプションが提供されます。Continueは、「例外メカニズムで続行する」ではなく、「何も起こらなかったかのように続行する」、つまりスロー後の次のコード行で解釈されます。

于 2013-03-02T22:51:50.020 に答える