成瀬です。

U.Nakamura wrote:
> こんにちは、なかむら(う)です。
> 
> In message "[ruby-dev:34033] ruby coding guideline"
>     on Mar.13,2008 19:40:42, <naruse / airemix.com> wrote:
> | * long == pointer 前提不可 (LLP64等 (Win64))
> (中略)
> | * long はポインタと演算を行う整数で用いる
> 
> いきなり矛盾してますよぅ。
> 
> trunk前提だと、SIGNED_VALUEを使ってください、が答えになりそう
> です。
> 
> なお、1.8ではlong == pointerを前提にしてよくなります、というか、
> そうでないプラットフォームはサポートしていません。

この部分は問題提起に枕のつもりでした。
つまり、わたしの読み取った限りでは、long はポインタとの演算用として
用いられているのに、LLP64 があるために破綻していると。

なお、実際の例として、String や Array の長さや添え字、
加えて Fixnum が long ベースですね。

[ruby-dev:29024] Fixnum on IL32LLP64 では long のサイズが
ポインタよりも小さい環境での悲哀が語られています。
Fixnum のベースを SIGNED_VALUE に切り替える案がでましたが、
結局ここではいくつかの問題によってとん挫しています。

具体的には、[ruby-dev:29054] にありますが、SIGNED_VALUE に切り替えた場合、
* FIX2xxx の名前
* printf で Fixnum の数値を出力したい場合、書式指定子がアーキテクチャ依存
* 変更が複雑
あたりがネックになったようです。

さて、より楽な代案として、SIGNED_VALUE の代わりに intptr_t を使うのはどうでしょう。
名前は FIX2INTPTR なり FIX2PTR でいいでしょうし、
書式指定子は %"PRIdPTR" が C99 で標準化されています。
(intmax_t に対応する %j か %"PRIdMAX" で代替もいいかも)

また、変更は long を intptr_t に置き換えるだけです。
なにより、1.8 時代での long == pointer の仮定を、
仕様から常に成り立つ intptr_t == pointer に移して続行できるのは楽でしょう。
さらに、SIGNED_VALUE と違って C99 で標準化されている型なので、
エディタ等の支援も多少期待できるかもしれません。

> あと、私が知っていて既に誰かが踏んだことがある問題としては、
> 
> * 配列を負のインデックスでアクセスするのは不可(C規格でも未定
>   義動作)
> 
> というのがありますね。

なるほど、負が絡むものだと、負の値の右シフトとかも実装依存でしたね。

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