[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[FDclone-users:00351] Re: FDclone でファイルサイズが 0 と表示される



 しらいです。

In Message-Id <OF760D0023.654CB76F-ON49256F60.0010EED7@tky.lightwell.co.jp>
        SHIOTA Shoichi <Shoichi.Shiota@lightwell.co.jp>さんwrites:
> 潮田です。

> >  long long が存在しないと思って compile してしまっている訳
> > ですから、その前提に基づいて compile された結果、4GB 以上の
> > 数値というのは扱えないんですよ。
> なるほど。

 64bit 幅の数値を扱えない conpile 環境でも、8byte 分の char
型配列として扱って、それ用の四則演算関数を作ってしまえば対応
は可能です。
 でも、本当にそういう環境なのだとしたら、off_t や size_t が
64bit 幅の筈がないので、64bit 幅の型を扱っている以上は long
long に匹敵する型を持っている筈です。
 なので、正式な対処は HAVELONGLONG なんだと思いますが、これ
は Configure 以外では自動検出出来ないんです。

 C99 での追加仕様なので、C99 対応であることが自動検出出来れ
ばいいんですけどね。
 現状では、C89 (ANSI C) 以上かどうかを識別子 __STDC__ で見
て、C89 以上なら大概 C99 だろうと見なして HAVELONGLONG 扱い
にしています。乱暴ではありますが。
 でも、C89 どころか C99 にまで準拠している癖に __STDC__ を
pre define しない compiler がたまにあるんですよね。AIX の cc
が正にそれな訳で。__STDC__ は ANSI 規格なんですけどね。

# IBM も PC 部門を売却予定だそうで、となると AIX なんても
#うとても面倒見切れない存在になっちゃうのかなー。


> >  具体的には負数分だけ算術シフトしようとして変な値を得ている
> > んでしょうね。負数分の算術シフトはどうも実装依存のようで、他
> > の環境ではなかなか再現しませんでした。
> 変な環境でしか再現しない問題のために、お手数をおかけしました。

 大抵の cc は演算子「>>」「<<」をそのまま CPU のシフト演算
mnemonic に置換えて処理しますから、負数を与えた場合にどうな
るかは CPU に依存します。
 負数は CPU 的にはとても大きい正数という扱いになるので、bit
幅を越えたシフト演算と同じ処理になると思います。無駄を承知で
本当にその回数のシフトを行なう実装やら、bit 幅を越えない範囲
で丸めてシフトを行なう実装やら色々あります。
 手元にある環境では、alpha と ARM と IA64 が前者で、i386 と
PA-RISC が後者ですね。前者だとシフト結果が 0 になってしまう
ので弊害が大きいんですが、後者だとなかなか気づきません。

 どちらの実装が「変」ということはないのですが、最近の Linux
ブームで i386 な環境が当たり前になってきているので、そうじゃ
ない環境を探すのに手間取ってしまいました。
 前者のうち alpha と IA64 は元々 int 幅が 64bit なので long
long を使わなくても何の問題もなくて、ARM を使って初めて症状
が再現出来ました。

# とは言え、ARM 機が Zaurus と某携帯ゲーム機しか無かったの
#で、どっちも処理の遅さで try & error が面倒で面倒で。


> ファイルサイズが小さい内は一覧・最下行とも正しく表示され、
> 大きなファイルサイズのものは、一覧が 999999999 、最下行が
> 2147483647 と固定値で表示されるようになりました。

 size_t は unsigned なので本当は「%u」で受けたいところなの
ですが、FDclone の内部処理では file size を size_t ではなく
off_t で扱っているので「%d」にしているんです。
 その結果、表示可能な file size 上限が 2^32 - 1 ではなくて
2^31 - 1 になってしまっています。4GB が正しく表示出来ません。

 これは悩ましいところではあるんですが、off_t が 64bit なの
に size_t が 32bit という環境が存在するので、出来るだけ桁の
大きい方で size 情報を扱いたいという配慮なんです。
 勿論 unsigned off_t なんて型が標準で存在していればそれを使
うんですが、signed な off_t を使う以上、どこかで負数を拾って
来たらそれは error 扱いになっても負数として表示させないとい
けませんので。

 言語の型が後付けでほいほい追加されたりするからややこしい話
になるんですよね。そのうち 128bit 幅とか 256bit 幅とか必要に
なってきたらまた拡張するのかしらん...。

                                               しらい たかし