0

コードを書きました

void SEHtest(int i) {
  int s = 0;
  __try {
    cout << "code1" << endl;
    int j = 1 / s;
    cout << "code2" << endl;
  } __except((s = 1, i)) {
    cout << "code3" << endl;
  }
  cout << "code4" << endl;
  return;
}
int main() {
  SEHtest(-1);
  return 0;
}

そして私は出力を待っています

code1
code2
code4

しかし、私は

code1

そして無限ループ。

それはなぜです?

volatiles と j にキーネームを追加しても修正されませんでした。

4

2 に答える 2

4

実行を再開するたびに例外が再スローされるため、無限ループが発生します。s = 1トラップの原因となった命令 (この場合はゼロ除算) から実行が再開されるため、フィルターにの値を設定しても問題ありません。次のようにコードを再編成すると、例外が継続的にスローされていることがわかります。

int ExceptionFilter(int& s) {
  cout << "exception filter with s = " << s << endl;
  s++;
  return -1; // EXCEPTION_CONTINUE_EXECUTION
}

void SEHtest() {
  int s = 0;
  __try {
    cout << "before exception" << endl;
    int j = 1 / s;
    cout << "after exception" << endl;
  } __except(ExceptionFilter(s)) {
    cout << "exception handler" << endl;
  }
  cout << "after try-catch" << endl;
  return;
}

int main() {
  SEHtest();
  return 0;
}

結果は次のようになります。

before exception
exception filter with s = 0
exception filter with s = 1
exception filter with s = 2
...

s の値をロードする命令ではなく、0 で除算する命令で実行が再開されるため、例外はスローされ続けます。手順は次のとおりです。

1  set a register to 0
2  store that register in s (might be optimized out)
3  enter try block
4  output "before exception"
5  load a register from s
6  divide 1 by register (trigger exception)
7  jump to exception filter
8  in filter increment/change s
9  filter returns -1
10 execution continues on line 6 above
6  divide 1 by register (trigger exception)
7  jump to exception filter
8  in filter increment/change s
9  filter returns -1
10 execution continues on line 6 above
...

その例外から再開することはできないと思います。

于 2014-11-14T18:15:27.487 に答える