成瀬です。

Yukihiro Matsumoto wrote:
> まつもと ゆきひろです
> 
> In message "Re: [ruby-dev:34020] MurmurHash problem"
>     on Tue, 11 Mar 2008 17:32:57 +0900, Nobuyoshi Nakada <nobu / ruby-lang.org> writes:
> 
> |これではalignされていないwordアクセスを許さないシステムでは動き
> |ません。murmurhashaligned.cppというのもあるようですが、これまた
> |
> |* intが32bitでないとならない
> |* little endianでないとならない
> |
> |という制限がありそうです。
> 
> そうかあ。残念だなあ。またJenkinsハッシュに戻すかなあ。
> 
> |intが64bitのシステムでも32bit整数がある保証ってあるんでしたっけ。
> 
> 保証はないでしょうね。
\
C99 の stdint.h では uintN_t (N は 8,16,32,64) が必須になっていますから、
C99 対応のコンパイラならば存在します。
なので、32bit のシステムでは言うまでもなく、
64bit 対応のシステム (=これからのシステム) でもまず確実に 32bit 整数が
存在すると言ってよいかと思います。

以下のようなものを defines.h においたうえで uint32_t を使うようにすればよいかと。

#if HAVE_STDINT_H
# include <stdint.h>
#else
# if SIZEOF_INT == 4
#  ifndef int32_t
typedef int int32_t;
#   define int32_t int
#  endif
#  ifndef int32_t
typedef unsigned int uint32_t
#  endif
# endif
#else
# error ---->> int32_t is not defined. <<----
#endif


エンディアンは常にバイトごとに取っていくとかですかねぇ。
最新のコンパイラだとそのへんちゃんと良きにはからってくれそうな気がするのですが、
場合分けした方がいいのかなぁ。
# 厳密にやろうとすると実行時分岐が必要そうなのですが・・・。


ところで、Ruby 1.9 ってどの程度まで前提にしていいのですっけ。
* ANSI C である
* char は8bit で CHAR_BIT は 8
* char が singed 前提は不可
* int, long, pointer は32bit 以上の 2 の累乗
* int == long 前提不可 (LP64等 (多くの UNIX 系))
* long == pointer 前提不可 (LLP64等 (Win64))
* long long 前提不可 ?
* C99 前提は不可
* エンディアンは big/little を考慮 (__BIG_ENDIAN_ 等を前提にしてはならない)

あとは int と long の使い分けでしょうか。なんとなく、
* int はただの整数。
* long は文字列長や文字位置等、ポインタとの演算が行われうるもの。
かなぁと思っているのですが、LP64 だとint において 64bit 化の恩恵が受けられず、
LLP64 だと int == long != *void なので long を分ける意義がないなぁとか。
後者は intptr_t にしてもよさそうな気もします。

-- 
NARUSE, Yui  <naruse / airemix.com>
DBDB A476 FDBD 9450 02CD 0EFC BCE3 C388 472E C1EA