[迷信] FILE 型は構造体

今回は、C でファイル操作によく使う FILE 型に関する迷信です。FILE 型と書きましたが、このように呼ぶ人は、世間では意外に少なく、多くの人は FILE 構造体と呼びます。では、FILE 型は常に構造体であると考えてよいのでしょうか? 答えはもちろん No です。

その根拠を示すために、まずは JIS X3010:2003 における FILE 型の記述を引用してみましょう。

FILEは,ファイル位置表示子,結び付けられたバッファ(もしあれば)へのポインタ,読取りエラー又は書込みエラーが起こったかどうかを記録するエラー表示子(error indicator),ファイルの終わりに達したかどうかを記録するファイル終了表示子(end-of-file indicator)などストリームを制御するために必要なすべての情報を記録することのできるオブジェクト型とする。

JIS X3010:2003より引用

いろいろな情報を格納する必要がありますので、普通に考えれば構造体を使うことになるのでしょうが、構造体型ではなくオブジェクト型となっています。オブジェクト型というのは、関数型や不完全型ではないオブジェクトを表現するための型で、具体的には、算術型・ポインタ型・構造体型・共用体型・配列型の総称です。ですから、必ずしも構造体である必要はないのです。

とはいえ、多くの実装では FILE 型は構造体になっています。これは素直な実装ではありますが、本来隠蔽すべき実装の詳細をユーザーにさらすことになるためデメリットもあります。一部の関数(putcfeof など)をマクロやインライン関数として記述できなくなるものの、より堅牢な実装のためには、<stdio.h> ヘッダでは

typedef struct _iobuf FILE;

のように、FILE 型は宣言だけにとどめ、各関数の実装を行っている翻訳単位でのみ構造体の宣言を行うようにした方がよさそうです。しかし、残念ながらこのような実装は許されません。なぜなら、FILE 型はオブジェクト型でなければならず、構造体の宣言だけでは不完全型であってオブジェクト型にはならないからです。

このエントリーを含むはてなブックマーク