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

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



 しらいです。

In Message-Id <OFDE1680CF.900AC632-ON49257155.0004DCF5@tky.lightwell.co.jp>
        SHIOTA Shoichi <Shoichi.Shiota@lightwell.co.jp>さんwrites:
> 潮田です。

> と異なるファイルサイズのファイルで試しましたが、最下行には全て
>   2147483647
> と表示されました。

 いえ、それで合ってます。

 AIX の cc は __STDC__ を pre-define しないので、long long
型を扱えないものとして処理されます。
 printf() に渡された off_t 型 (実体は long long) は、AIX の
扱える (と見なされている) 最大幅である long 型に代入されるこ
とになります。
 ところが、4MB を越える値では off_t 型の上位 32bits が 0 で
ないため、long 型で表すことが出来ません。そこで仕方ないので、
MAXLONG 値を代用として代入します。
 MAXLONG = 2^32 - 1 = 2147483647 なので、この表示は期待通り
ですね。


> va_dcl; -> va_dcl
> を変更して、実行すると以下の様になりました。
> (AIX でも可変引数は使用できると思っているのですが、これも
>  OS の ver 依存なんでしょうね)

 「;」はこちらのミスです。vararg.h 環境がないもので。

 で、何故 AIX では stdarg.h でなくて vararg.h なのかと言う
と、上の __STDC__ のせいですね。K&R 準拠仕様だと思われてしま
い、vararg.h の方を使います。
 cc の代わりに xlc を使うと __STDC__ が pre-define されるの
で stdarg.h を使いますが、今度は同時に long long も扱える環
境になってしまうので今回の検証に役立ちません。


> $ ./fd
> 01 23 45 67 89 ab cd ef
> 7654456789ab3210
> 2147483647

 んー、期待通りの結果になってしまっていますねー。どういうこ
とでしょう?
 そもそも sscanf() が正しく機能出来ているかどうかを検証する
ため、「fprintf2()」を「fprintf()」に置換えて 3 行目の表示を
確認してみて下さい。「%qd」は「%lld」にして下さいね。
 その後で、[FDclone-users:00495] の patch を試してみて、こ
の結果がどう変化するかも見て下さい。この patch がないと正し
い値にならない筈なんですけどね。


> # エンディアンの違いと言う物を理解していないのが、丸分かりです。

 この問題は実は endian の問題だけではありません。

 endian が効いてくるのは int 幅以内の変数の実装であって、そ
れ以上の幅の変数は CPU の機能ではなく C compiler の用意した
コードで実装されています。
 CPU で普通に加減乗除出来る最大の桁数が仮に int 幅だったと
して、それ以上の幅の変数は int 幅の加減乗除を筆算の要領で繰
返して実装します。
 32bits CPU なのに long long を扱えるようにするには、32bits
幅の変数二つに分割して加減乗除を行ないます。この時、変数領域
の中でどっち側に置かれた 32bits を上位とするかは compiler が
決めることです。
 なので、big endian なのに long long を上位→下位の順で並べ
る実装や、その逆があってもおかしくはありません。

 因みに HP-UX の場合、変数領域の構造は endian の通りに置か
れますが、関数の引数にした場合は endian に反して下位→上位の
順で push されます。
 こういうややこしい OS 毎の差異を吸収するのは難しそうなので、
最終的には long long を扱える環境では極力 long long を使うよ
うにした方がいいでしょうね。
 なので、AIX も HAVELONGLONG を指定する方向で考えていますが、
今回の検証では敢えてこれを指定しないておいて、それでも最低限
の機能が実現出来るように工夫をしておきたいと思います。
 ひょっとすると不毛な検証に終わってしまうかも知れませんが、
世の中には「64bits 幅の変数を扱えるが long long を扱えない」
なんて粋狂な環境もあるかも知れませんので。

                                               しらい たかし