EXP31-C. assert() のなかでは副作用を避ける
このガイドラインは以下に統合されました。
assert()
マクロは、コードに診断機能を組み込むのに便利な仕組みである(「MSC11-C. 診断テストはアサートを使って組み込む」を参照)。標準の assert
マクロとともに使う式には副作用があってはならない。一般に、assert
マクロの動作はプリプロセッサシンボル NDEBUG
が定義されているかどうかによって異なる。NDEBUG
が定義されていなければ、assert
マクロはその式の引数を評価するように定義され、式の結果が false
に変換可能であれば、強制終了する。NDEBUG
が定義されていれば、assert
は無視される。この結果、非デバッグ版のコードでは、アサート内の式の評価により生じる副作用は発生しない。
assert
はマクロであるため、このルールは「PRE31-C. 安全でないマクロの引数では副作用を避ける」の特殊例である。
違反コード
void process(size_t index) { assert(index++ > 0); /* 副作用 */ /* ... */ }
適合コード
アサートでの副作用が発生する可能性を避けること。
void process(size_t index) { assert(index > 0); /* 副作用なし */ ++index; /* ... */ }
リスク評価
アサートでの副作用は、予期しない誤った動作を引き起こす可能性がある。
ルール |
深刻度 |
可能性 |
修正コスト |
優先度 |
レベル |
---|---|---|---|---|---|
EXP31-C |
低 |
低 |
低 |
P3 |
L3 |
自動検出
ツール |
バージョン |
チェッカー |
説明 |
---|---|---|---|
Coverity |
6.5 |
ASSERT_SIDE_EFFECTS |
副作用を起こす可能性のある操作/関数呼び出しがアサートに含まれる特殊例を検出できる。 |
ECLAIR |
1.1 |
macrcall |
実装済み |
LDRA tool suite |
V. 8.5.4 |
9 S |
実装済み |
PRQA QA-C | 8.1 | 3440 | 実装済み |
関連するガイドライン
CERT C++ Secure Coding Standard | EXP31-CPP. Avoid side effects in assertions |
CERT Oracle Secure Coding Standard for Java | EXP06-J. Do not use side-effecting expressions in assertions |
参考資料
[Dewhurst 2002] | Gotcha 28: "Side Effects in Assertions" |
翻訳元
これは以下のページを翻訳したものです。
EXP31-C. Avoid side effects in assertions (revision 52)