4

例外安全なコードを記述する場合、呼び出されるすべての関数の例外安全性の保証 (none、basic、strong、または no-throw) を考慮する必要があります。コンパイラは何の助けにもならないので、ここでは関数の命名規則が役立つのではないかと考えていました。関数によって提供される例外の安全性保証のレベルを示す確立された表記基準はありますか? 私はハンガリーのようなものに沿って考えていました:

void setFooB(Foo const& s); // B, offers basic guarantee
int computeSomethingS();    // S, offers strong guarantee
int getDataNT() throws();   // NT, offers no-throw
void allBetsAreOffN();      // N, offers no guarantee

編集:この種の命名規則は醜いというコメントに同意するので、提案する理由を詳しく説明させてください.

一部のコードをリファクタリングし、そのプロセスで、関数によって提供される例外の安全性のレベルを変更するとします。保証が、たとえば強力なものから基本的なものに変更された場合 (おそらく速度の向上によって正当化されます)、リファクタリングされた関数を呼び出すすべての関数は、例外の安全性について再検討する必要があります。保証の変更によって関数名も変更された場合、コンパイラは、少なくとも変更された関数のすべての使用にフラグを立てることで、私を少し助けることができます。これは、問題のある上記の命名規則を提案する私の理論的根拠でした。これは const と非常によく似ています。関数の const 性を変更すると、他の呼び出し関数にカスケード効果が生じますが、その場合、コンパイラは非常に効果的な支援を提供します。

したがって、私の質問は、特にコードのメンテナンスとリファクタリング中に、コードが意図した例外保証を実際に満たすようにするために、人々がどのような作業習慣を開発してきたかということです。

4

4 に答える 4

5

私は通常、関数がスローされないことが保証され、例外の安全性が重要であることが確実な場合にのみ、例外仕様でタグ付けすることが多いことをコメント (doxygen) で文書化しています例外のthrow() 保証は例外です。

つまり、私は通常、未処理の例外が問題を引き起こすコードの部分での例外についてより心配し、それをローカルで処理します (RAII などの他の方法でコードが例外に対して安全であることを確認し、外部で作業を実行してから、これは、私が積極的に としてマークしている唯一の機能に関するものthrow()です。

他の人は別の経験をしているかもしれませんが、私の日常の仕事にはそれで十分だと思います.

于 2011-08-13T22:43:35.243 に答える
3

特別なことをする必要はないと思います。

私が実際に文書化しているのは非スローのみです。これは、言語の構文で許可されているためです。

プロジェクトには、保証を提供しないコードがあってはなりません。そのため、文書化するのは強い/基本的なものだけです。これらについては、メソッド自体ではなくクラス全体に関するものであるため、明示的に呼び出す必要はないと思います(これら2つの保証のため)。それらが提供する保証は、実際には使用法に依存しています。

私はすべてに強力な保証を提供したいと思います (しかし私は提供しません)。

于 2011-08-14T00:33:23.400 に答える
1

うまくやりたいというあなたの意欲は理解していますが、そのような命名規則については確信が持てません。

私は一般的に、言語によって強制されていない命名規則に警戒しています。それらは最大の嘘つきになる傾向があります。

そのようなものが本当に必要な場合は、コンパイラ (Clang など) を手に入れて、新しい属性セットを追加することをお勧めします。標準ライブラリが提供するヘッダーと、依存するすべてのサードパーティのヘッダーを編集して、注釈を付けて、それらの保証を最初から取得できるようにする必要があることに注意してください。

次に、コンパイラに注釈をチェックさせることができます(どちらも簡単ではありません...)。注釈はをつくことができないため、有用になります。

于 2011-08-14T13:12:53.137 に答える