0. Null

C言語のgetchar()は標準入力ストリームから文字を1つ読んで返す。 ただし、ストリームの終端(EOF)に達するか、エラーが発生したときは定数EOFを返す。 この定数は負の整数値で定義されている。

文字は1バイトなので、戻り値の型はcharでも良さそうな気がする。 しかし、charがとりうる256種類の値と「EOFまたはエラー」を合わせた257種類の値を表現できる型でなければならないので、戻り値の型をcharにすることはできない。

このように、APIには2種類以上の結果†1を返すものがあり、 呼び出し元が戻り値を確認して結果はそのいずれなのかを調べなければならないものがある。 そして、特別な結果を示すための定数†2(上記の例ではEOF)が定義されている。

†1 通常の処理と例外処理、 のような表現は相応ふさわしくない。 getchar()にとってEOFは例外処理ではないからだ。 getchar()はストリームからの文字の取得、 EOFの検出または入力エラーの検出の2種類の結果を知らせる。

†2 いわゆる番兵ばんぺい(sentinel value)のこと。 Wikipedia [1] を参照。

そして、ポインタを返すAPIのなかには、 失敗を表すためにNULLヌル(nullポインタ)を返すものがある。 fopen()malloc()などは要求に応えられなかった場合に、 strstr()strchr()などは「見つからなかった」場合に、その値が返る。 戻り値のポインタがNULLかどうかを調べずにそのポインタを使用すると、 恐ろしいことになる。というのは、何が起こるかは決まってないからだ。

オブジェクト指向言語の参照にも、 C言語のnullポインタと同様、 何も参照してないことを示すnullnilなどが定義されていることが多い。 それらをnull参照null reference)と呼ぶ。 Wikipedia [2] の説明を次に引用しておく:

a null pointer or null reference has a value reserved for indicating that the pointer or reference does not refer to a valid object.

ただし、例えばJavaではnull参照をたどって(null dereferencingして)も、 規定の例外をスローするだけで、 特別恐ろしいことは起きない。 ifで参照がnullかどうか調べ忘れないようにすればよいだけだし、 忘れても例外がスローされるだけだ。

しかし、ifnullをチェックすること、 いわゆるnullチェック、がnull参照を正しく扱う唯一の方法ではない。 いくつかの言語でnull参照をどう取り扱えばよいか考えてみよう。

References

  1. Wikipedia, Sentinel value

  2. Wikipedia, Null pointer