JPCERT コーディネーションセンター

EXP06-J. アサーションに副作用を持つ式を使わない

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)

Top へ

Topへ
最新情報(RSSメーリングリストTwitter