タイトルの質問に対する簡単な答え-関数がスローできることを示すイディオムは、「この関数はスローしない」ことを文書化することではありません。つまり、デフォルトですべてをスローできます。
C ++はJavaではなく、コンパイラーによってチェックされる例外はありません。C ++には、コードがスローしないと主張していることをコンパイラーが通知できるようにするものはありませんが、スローする可能性のあるものを呼び出します。したがって、これが実行時の問題であることを完全に回避することはできません。静的分析ツールが役立つかもしれませんが、確かではありません。
MSVCのみに関心がある場合は、空の例外仕様を使用するか__declspec(nothrow)
、スローしない関数、およびスローする関数を使用することを検討できthrow(...)
ます。MSVCは、nothrowと宣言された関数が実際にスローしないことを確認するコードを発行しないため、これによって非効率的なコードが生成されることはありません。GCCはで同じことを行うことができ-fno-enforce-eh-specs
ます。コンパイラのドキュメントを確認してください。その後、すべてが自動的に文書化されます。
オプション2、アプリ全体のtry-catchは、実際には「安全のため」ではありません。C++ランタイムを呼び出すよりも、例外を除いて(何かを印刷してきれいに終了するなど)もっと便利なことができると思うからですterminate
。何かがスローされないという前提でコードを記述していて、実際にスローされる場合、たとえば、デストラクタが一貫性のある状態を誤って想定している場合など、どちらかが実際に発生する前に未定義になっている可能性があります。
私は通常、(1)の変形を行います。各関数ドキュメントに対して、それが提供する例外保証(nothrow、strong、weak、またはnone)。最後はバグです。最初のものは貴重ですがまれであり、優れたコーディングはスワップ関数とデストラクタにのみ厳密に必要です。はい、ユーザーエラーが発生する可能性がありますが、例外を除いたC++コーディングの手段はユーザーエラーが発生する可能性があります。次に、その上で、(1)を実施するのに役立つ場合は、(2)および/または(3)も実行します。
Symbianには、いくつかの点で例外のような「脱退」と呼ばれるメカニズムを備えた、C++の先行標準方言があります。Symbianの規則では、終了する可能性のある関数には、末尾にLを付けて名前を付ける必要があります:CreateL
、、ConnectL
など。終了する可能性のあるものを呼び出しているかどうかをより簡単に確認できるため、平均してユーザーエラーが減少します。ご想像のとおり、アプリのハンガリアン記法を嫌うのと同じ人々がそれを嫌い、ほとんどすべての機能がなくなると、それは役に立たなくなります。また、ご想像のとおり、名前にLが含まれていない関数を作成する場合は、デバッガーで問題を特定するまでに長い時間がかかる可能性があります。これは、仮定が実際のバグから離れていることを示しているためです。