01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
Value too large for defined data type
とかエラーを出す。 どうやらファイルサイズが 2G を越えているのが原因らしい。 UNIX では「2G の壁」とい
うものが存在する。 これは lseek() など、ファイル内の読み出し位置を移動する関数に 与えるオフセット値が
伝統的に signed long であるためである。 signed long では 2147483647 、要するに 2G バイトまでしか表現で
きないので これを越えると単に fseek()に渡せないだけでなく、 内部の位置計算処理に多大な混乱が起こる
(ちなみに相対位置指定のために負の値も必要)。
最近の UNIX では 2G を越えるファイルもサポートしている。 ただし、従来のプログラムが混乱することを防
ぐために 2G を越えるファイルは 通常の open() では開けない (エラーになる)ようになっている。 前述のエ
ラーメッセージは 2G を越えるファイルを開こうとしたときに perror() が返すエラーメッセージである。
んで、2G を越えるファイルを使いたいときは 以下のような definition を入れてコンパイルすればいいらしい。
gcc hoge.c -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
こうすると、stdio.h の中で、 open() や lseek() とかを 2G 以上のファイル対応の関数にマップしなおしてくれ
るようだ。 オフセット指定の型は off_t 型となっていて、これに対応する実際の型も従来の long から long long
になる。
long long 型はまだ ANSI 規格にはないらしいのだが、 gcc では 64 bit の整数型として実装されている。 多分ほ
かのコンパイラにもあるのだろう。
これで、コンパイルし直せばなんでも OK かというとその辺はちょっと怪しい。 off_t 型を int や long に代入す
るというようなコードは十分あり得るからだ、 まあこういう場合はおそらく警告が出るだろう。