19

過去に Visual C++ 2010 の自動例外発生機能が非常に便利であることがわかりました。今日、このダイアログ ボックスのオプションを調べていたところ、例外の種類の 1 つが "void" であることがわかりました。これは何を意味するのでしょうか?これを選択した場合、コードでスローされた例外で中断しますか? そうでない場合、どのような種類の throw ステートメントがこのタイプのブレークポイントをトリガーしますか?

Visual Studio 例外ダイアログ

より一般的なフォローアップの質問は、このダイアログとそのすべてのオプションに関するドキュメントはどこにありますか?

4

3 に答える 3

12

それがどのように機能するかについて(MSaltersが述べたように)、これは単に間違った命名に関するものです。

void*もちろん、実際には名前が付けられます。

しかし、なぜそれint*const char*など (実際には、ユーザー定義型へのポインターを含む任意のポインター型) で機能するのでしょうか?

これは、非常に興味深い C++ 例外処理の問題に関連していると推測できます。catch(void*)例外ハンドラーは、(cv 互換の) ポインター型の例外を実際にキャッチします

例:

try
{
   throw "Catch me if you can!";      
}
catch(void* e)
{
   // ...and I can!
   std::cout << "Gotcha!" << std::endl;
}

ここでは、スローchar*(Visual C++ では char リテラルはchar*ではなくconst char*) をスローし、 でキャッチしvoid*ます。そしてそれはうまくいくでしょう!

答えは C++ Holy Standard にあります:

§15.3 例外の処理

15.3.3 次の場合、ハンドラーはタイプ E の例外オブジェクトに一致します。

...

ハンドラーの型は cv1 T* cv2 であり、E はポインター型であり、次のいずれかまたは両方によってハンドラーの型に変換できます — 標準のポインター変換 (4.10) で、プライベート クラス、プロテクト クラス、またはあいまいなクラスへのポインターへの変換は含まれません。

...

そして4.10は、標準のポインタ変換には次への変換が含まれると言っていますvoid*

4.10.2 「cv T へのポインター」型 (T はオブジェクト型) の prvalue は、「cv void へのポインター」型の prvalue に変換できます。

また、Visual Studio デバッガーも同様に機能しますが、正確にはこの方法ではないことに注意してください。違いは、cv 修飾子を無視することです。したがってvoid、例外ダイアログでは、実際には any を意味します[any cv] void*。Catch ハンドラはそれらを無視しません:

try
{
   struct Throwee {};
   const Throwee* t = nullptr;
   throw t;      
}
catch(void* e)
{
   // Will be missed
   std::cout << "Gotcha!" << std::endl;
}
catch(const void* e)
{
   // Will be catched
   std::cout << "Gotcha const!" << std::endl;
}
于 2013-01-29T16:51:13.997 に答える
4

void*int*またはをスローすると壊れることがわかりましたが、ではchar const*ありませんint

于 2013-01-29T08:41:30.610 に答える
0

それがcatch(...)の設定なのかもしれません。それが伝播したthrow;ステートメントのいずれか。

于 2013-01-28T21:48:49.600 に答える