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 に代入するというようなコードは十分あり得るからだ、 まあこういう場合はおそらく警告が出るだろう。