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

FIO12-C. setbuf() ではなく setvbuf() を使用する

FIO12-C. setbuf() ではなく setvbuf() を使用する

setbuf() 関数は、setvbuf() 関数に置き換えることができる。

(void) setbuf(stream, buf);

は、

(int)setvbuf(stream, buf, _IOFBF, BUFSIZ);

または、buf が NULL ポインタの場合は

(int)setvbuf(stream, buf, _IONBF, BUFSIZ);

と等しい。

C99 のセクション 7.19.5.5 では、setbuf() を以下のように定義している。[ISO/IEC 9899:1999]

setbuf 関数は、値を返さない点を除けば、mode を値 _IOFBFsize を値 BUFSIZ とした setvbuf 関数と等価とする。ただし、buf が空ポインタの場合は、mode を値 _IONBF とした setvbuf 関数と等価とする。

ゆえに、ストリームが正しく変更されたことを確認するには setbuf() ではなく setvbuf() を使用するべきである。

違反コード

以下のコード例は、buf 引数に NULL を使用して setbuf() を呼び出す。

FILE *file;
/* file の設定 */
setbuf(file, NULL);
/* ... */

setbuf() の呼び出しが成功したかどうかは判別できない。

処理系固有の詳細

4.2BSD および 4.3BSD システムの setbuf() が使用するバッファサイズは最適ではないため、使用を避けるべきである。

適合コード

以下の解決法は、setvbuf() を呼び出しており、この関数は操作が失敗すると 0 以外の値を返す。

FILE *file;
char *buf = NULL;
/* file の設定 */
if (setvbuf(file, buf, buf ? _IOFBF : _IONBF, BUFSIZ) != 0) {
  /* エラー処理 */
}
/* ... */
リスク評価

setbuf() を使用するとエラーの捕捉に失敗し、プログラムの間違った実行につながるおそれがある。

レコメンデーション 深刻度 可能性 修正コスト 優先度 レベル
FIO12-C P2 L3
自動検出

Compass/ROSE はこのレコメンデーションの違反を検出できる。

参考情報
翻訳元

これは以下のページを翻訳したものです。

FIO12-C. Prefer setvbuf() to setbuf()

Top へ

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