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

[jfriends] Re: Nothing, Null, Empty




前橋です。

えんどう さん:
># あ、そうだ、前橋さん JavaHouse-Brewers ML 参戦おめでとうございます。
># これで思う存分論戦できますね。(^^(

ネタがネタだけについ突っ込んでしまいました(こっちのMLでは何度か
話題にしていることですけどね)。ついでに、変なところで改行が入る
オマケ付き、ああ(;_;)

>> CやJavaで、SQLのNULL相当品がないのは、
>値が不定っていうのがいやだったのだと思います。

SQLのNULLは不定ではありません。無効な値というか、値が設定されて
いない状態というか。

たとえば、Cでは、ローカル変数(というか自動変数)の値は、初期化し
なければ不定です(処理系によるけど)。malloc()で確保した領域の中
身も不定でしょう。

こういう状況だと、初期化を忘れた場合、同じプログラムが動いたり
動かなかったりします。バグっても、再現できないかも知れません。
これでは困るってんで... どうなっていればいいと思います?

案1)
・ローカル変数は、整数型はゼロ、浮動小数点数はは0.0、ポインタは
  NULLで初期化するように、実行系が気を使う。
・malloc()なんぞ使わずにcalloc()を使う。

案2)
・ローカル変数の領域は、関数に突入した時点で、0xCCみたいなグチャ
  グチャのビットパターンで埋める。
・malloc()は直接呼ばずに一枚皮をかぶせて、0xCCみたいなグチャグチャ
  のビットパターンで埋める。

# ローカル変数は処理系にがんばってもらわなければ駄目だけど、
# malloc()の方は今日からでも実践できますね。

さて、どっちがいいでしょう?

当然、案2の方ですよね。

ゼロは、変数の初期値として、比較的ありがちな値です。ということは、
ゼロなんぞで勝手に初期化してしまうと、何かのはずみでその変数への
代入を忘れた場合など、運が *悪い* と、プログラムは正常動作してしま
います。enum なんかは、デフォルトでゼロから始まるので、特に危険です。

それに対し、0xCC の方は、まあこんな変な値がいきなり入ってたら、
プログラムはまず確実に変な動きをするか、もっと運が *良ければ*、
coreを吐いて死んでくれるでしょう。そうなればしめたものです。
デバッガで原因を追跡して、バグを潰せば良いのです。

デバッガで見て、0xCCが並んでいたら、ああ、この辺は初期化されてい
ないんだなあ、ということも分かりますし。

ただ、もちろん、これには問題もあって、0xCC という値が、もしたまたま
正当な値であった場合、やっぱり正常動作してしまうということです。
確率的には低いですが、あり得ないことではありません。

そこで登場するのがNULLです(C だと紛らわしいけど、SQLのNULLの意味で)。
NULLが無効な値であることが保証されていれば、0xCCみたいな変な値を使
わなくても、安心して無効な状態として扱うことができます。

余談ですけど、

もし、テストフェーズをすり抜けてしまった場合(案2 なら、案1 に比べて、
バグがテストをすり抜ける確率はかなり下がりますが)、プログラムはユー
ザの前で死んでしまうかもしれませんが、一見正しいが、実はちょっと違う
計算結果を出したり、半年かかって作ったデータが、(一見正しいが)次の
工程に回せなかったりするよりはマシでしょう。

>>   んー、本当は、NULL欲しいんだけどなー、でも、そうすると、
>>   intが32bitなら、1ビットどっか別の所によけいにとるか、
>>   32bitのうちの1bitを「有効無効フラグ」に回さなきゃいかんしなー、
>>   「1ビットだけ」別の所にとると、バス幅と違うから遅くなるし、
>>   そのためだけに8bitとか32bitとか取るのもなあ。
>>   だからって、32bitのうち 1bitをフラグにすると、有効桁数減っ
>>   ちゃうし、ハードの演算命令を使えなくなっちゃうしなあ。
>どう実現しているかは知りませんが、
>Java には infinity とか NaN という値もありますです。

これはIEEE754(だったかな)で規定されている値ですね。浮動小数点数
にはあるけど、intにはありませんよね。

>えんどう説は
>説1「値が不定っていう状態があってもいいや」
>説2「値が不定っていう状態が無いのは許せん!」
>
># 1かな...

前橋説は、
「値が設定されていないという状態がないのは許せん!」
です。

ただ、私が Cや Java相当の言語を設計するのなら、C はもちろん、Java
みたいなインタプリタ言語でも、「値が設定されていない状態」を保持で
きるようにはしないと思います。これはやっぱり効率のためです。

>> ええと、他の型(Integerとか)には、NULL相当品はないんでしょうか?
>Integer みたいなプリミティブ型はゼロで初期化されたと思います。
>(嘘かも)

うーむ、IntegerとかにもNULL相当品があって、Variantに暗黙の型変換
機能があるのなら(整数の1を代入したのに1.0にも見えるとか)、NULLで
Emptyを代用する手もあったかもしれませんが、そうじゃないとなると
やっぱりEmptyが必要ですかねえ。

                                                    de 前橋