EXP12-C. 関数の返り値を無視しない
関数に副作用があるかないかに関わらず、多くの関数は役に立つ値を返す。たいていの場合この値は、関数が処理に成功したか、あるいはエラーが発生したかを示す(「ERR02-C. 正常終了時の値とエラーの値は別の手段で通知する」を参照)。それ以外の場合、値は比較の結果で、関数の API の整数部分となる。
C 標準 [ISO/IEC 9899:2011] セクション 6.8.3 には次のように記載されている。
返り値を無視された関数呼び出しなどすべての式文は、暗黙的に void にキャストされる。
返り値にはエラーの可能性など重要な情報が含まれていることが多いので、常にチェックするべきである。そうでなければ、明示的にキャストしてプログラマの意図を表すこと。関数が有意味な値を返さないのであれば、返り値を void
型として宣言するべきである。
このレコメンデーションは「MEM32-C. メモリ割り当てエラーを検出し、対処する」、「FIO04-C. 入出力エラーを検出し、処理する」、「FIO34-C. 文字入出力関数の返り値の取得には int 型を使用する」を包含している。
違反コード
以下のコード例は、puts()
を呼び出し、書き込みエラーが発生したかどうかをチェックしていない。
puts("foo");
しかし、puts()
は失敗し EOF
を返す場合がある。
適合コード
この適合コードは出力エラーが発生していないことを保証している。(「FIO04-C. 入出力エラーを検出し、処理する」を参照。)
if (puts("foo") == EOF) { /* エラー処理 * / }
例外
EXP12-EX1: 返り値が重要でないあるいはエラーを無視しても安全なら(たとえば副作用の結果呼び出された関数の場合)、その関数は明示的にvoid
にキャストし、プログラマの意図を示すべきである。この例外の例としては、「FIO10-C. rename() 関数の使用に注意する」のセクション「可搬性のある動作」にある適合コードを参照のこと。
EXP12-EX2: 関数呼び出しが必ず成功するあるいは返り値がエラー条件を示さないのであれば、返り値を無視できる。自動検出ツールを使う場合、そのような関数はホワイトリストに登録するべきである。
strcpy(dst, src);
リスク評価
関数が返すエラーコードやその他の値をチェックし損ねると、間違ったプログラムのフローやデータの完全性違反につながる恐れがある。
レコメンデーション |
深刻度 |
可能性 |
修正コスト |
優先度 |
レベル |
---|---|---|---|---|---|
EXP12-C |
中 |
低 |
中 |
P4 |
L3 |
自動検出(最新の情報はこちら)
ツール |
バージョン |
チェッカー |
説明 |
---|---|---|---|
Compass/ROSE |
|
|
|
Coverity |
6.5 |
CHECKED_RETURN |
関数呼び出しから返される値の処理方法の不一致を検出する。Coverity Prevent では、このレコメンデーションに対する違反をすべて検出できるとは限らないため、さらなる検証が必要である。 |
ECLAIR |
1.1 |
ignrtrn |
実装済み |
V. 9.1 |
SV.RVT.RETVAL_NOTTESTED |
|
|
LDRA tool suite |
V. 8.5.4 |
382 S |
実装済み |
PRQA QA-C | 8.1 | 3200 | 実装済み |
Splint |
V. 3.1.1 |
|
|
関連するガイドライン
CERT C++ Secure Coding Standard | EXP12-CPP. Do not ignore values returned by functions or methods |
CERT Oracle Secure Coding Standard for Java | EXP00-J. 関数の返り値を無視しない |
ISO/IEC TR 24772:2013 | Passing Parameters and Return Values [CSJ] |
MITRE CWE | CWE-754, Improper check for unusual or exceptional conditions |
参考資料
[ISO/IEC 9899:2011] | Section 6.8.3, "Expression and Null Statements" |
翻訳元
これは以下のページを翻訳したものです。
EXP12-C. Do not ignore values returned by functions (revision 64)