関数に noexc 属性を追加する必要があるのはどのような場合ですか?つまり、コンパイラが関数のスローを認識できないのはどのような場合ですか?すべてにマークを付ける必要がありますか? それともそれを見分ける方法はありますか?
私は時期尚早な最適化は好きではありませんし、時期尚早な帰属も好みません。 「プロフィール」の方法がわかりません。最適化時にパフォーマンスをプロファイリングするのと同じ方法で、 noexc が必要です。
必要に応じて評価する場合は、最も一般的なコンパイラについてコメントしてください。 MSVC、GCC など
stackoverflow.com/ に注意してください。質問/10787766/…セマンティクスについて話していますが、必要性や使用法については話していません。 (日付も付いています)
– j__
2020 年 9 月 3 日 16:32
1
必要性についても触れています。例: stackoverflow.com/a/12560616/1625187 この質問は私にとってはカモに見えます。
– Evg
2020 年 9 月 3 日 16:38
関連: stackoverflow.com/questions/63727438/…
– j__
2020 年 9 月 3 日 16:39
------------------------
C++ コア ガイドラインでは、基本的にコードがスローしない場所ではどこでも使用することを推奨しています。これはライブラリにとって最も重要です。コード チェッカーは、呼び出した関数を使用して noExcept かどうかを確認します。そうでない場合は、一連の警告が表示されます。
とはいえ、最も重要な推奨事項は、スワップ、移動、デストラクターを例外なく行うことです。
C++ コア ガイドラインでも次のことが推奨されています。デフォルトのコンストラクターを no以外に修正することは一般的には優れていますが、多くのパターン (pImpl イディオムなど) では、デフォルトのコンストラクターにメモリが割り当てられることがよくあります。したがって、私は通常、デフォルトのコンストラクター (またはデフォルトのパラメーターのみを取るコンストラクター) で noExcept を使用しますが、スローできることがわかっている場合は、明示的に nothrow(false) とマークするようにしています。
デフォルトのコンストラクター、コピー コンストラクター、代入演算子、移動コンストラクター、移動演算子、またはデストラクターを =default として宣言すると、暗黙的に noexc になります。すべてのデストラクターも暗黙的に noExcept です。
「これがスローされた場合は、先に進んでクラッシュしてください」という意味以外には、何かをマークできるという概念があります。私はこの概念が少し面倒だと思うので、私のコードでは、noExcept(false) または Leave をスローできるものにマークを付けています。それは不特定です。これは通常、new を呼び出すか、std コンテナを初期化するものです。
------------------------
関数に noexc 属性を追加する必要があるのはどのような場合ですか?
関数が決してスローしないことを文書化して強制したい場合。
ここでの間違いは、例外を伝播する代わりに std::terminate() の呼び出しが行われることを意味することを思い出すことが重要です。このため、悲観的な見方になる可能性があります。
つまりコンパイラが関数のスローを認識できないのはどのような場合ですか?
これは逆です。コンパイラは、そうでないことが証明できない限り (またはそうではないと言われます)。
必要な定義があれば証明できます。たとえば、LTO を使用しない TU 間では、LTO は機能しません。
「プロファイル」する方法がわかりません。例外は必要ありません
他の場合と同様に、ありとなしで測定します。
ほとんどのプロジェクトでは、LTO を有効にすることに取り組むことが、それに対処するより良い方法です。