assert()文はコードに診断テストを組み込むための便利な機能である。標準のassert文に用いられる式は副作用を含んではならない。一般に、assert 文は実行時の設定に従って動作する。有効にすると引数の式を評価し、評価結果がfalseである場合には AssertionError を投げる。無効にすると、assert文は何もしない、つまり、式を評価したら発生したはずの副作用は発生しない。したがって、プログラムは副作用を持つ式をアサーションに用いてはならない。
違反コード
以下の違反コード例では、アサーションの中でリストからすべてのnullを削除しようとしている。しかし、アサーションが無効にされると、boolean式は評価されなくなる。
private ArrayList<String> names; void process(int index) { assert names.remove(null); // 副作用 // ...
適合コード
アサーションの中では副作用が発生する可能性を避けること。これは、boolean式をアサーションとは別の式にすることで実現できる。
private ArrayList<String> names; void process(int index) { boolean nullsRemoved = names.remove(null); assert nullsRemoved; // 副作用はない // ... }
リスク評価
アサーションに副作用が存在すると、プログラムの動作がアサーションが有効であるか無効であるかに依存してしまう。
ルール | 深刻度 | 可能性 | 修正コスト | 優先度 | レベル |
---|---|---|---|---|---|
EXP06-J | 低 | 低 | 低 | P3 | L3 |
自動検出
副作用の発生がローカルなスコープから見えるアサート式を検出するのは容易である。場合によっては、どのメソッドが副作用を持たないかをプログラマがツールに知らせてやる必要がある。
関連ガイドライン
CERT C Secure Coding Standard | EXP31-C. Avoid side effects in assertions |
CERT C++ Secure Coding Standard | EXP31-CPP. Avoid side effects in assertions |
参考文献
[Tutorials 2008] | Programming With Assertions |
翻訳元
これは以下のページを翻訳したものです。
EXP06-J. Do not use side-effecting expressions in assertions (revision 67)