2005-10-06
空ポインタ定数というのは、いわゆるNULLのことです。厳密には、0に評価される汎整数定数式のことを指します。空ポインタ定数は、いかなるオブジェクト型、不完全型、関数型へのポインタとも等しくなりません。
歴史的な経緯からC++ではNULLより整数リテラルの0が使われることが多いようです。CではNULLマクロが(void*)0に定義されることもありますが、C++では、NULLマクロは通常0または0Lに定義されます。これは、C++ではvoidへのポインタから他の型のポインタに暗黙的に変換されることがないからです。
さて、C++では空ポインタ定数として0を使うことが多いと上で書きましたが、0というのは当然intになります。C++では多重定義をはじめ、正確な型が必要になる場合が多々あります。そんなときは、NULLの代わりに単なる0を使うだけでは済まないのです(かといってNULLマクロを使ったとしても解決するわけではありませんが)。
関数の引数や多重定義された演算子のオペランドがポインタの場合、空ポインタ定数を渡すには、正しい型にキャストしてやる必要があります。そうしなければ、単なる0はintと解釈され、多重定義の解決があいまいになってコンパイルできなかったり、期待した関数とは異なる関数が呼び出されたりしてしまいます。
また、NULLマクロを使う場合には、マクロの定義内容が普通は0または0Lですので、intなのかlongなのかも処理系定義になってしまい、特に移植性において深刻な問題を引き起こしてしまいます。
さらに、可変個引数の場合に0を渡すと、いっそう深刻な状況が待っています。これはCでも同じことですが、ポインタのサイズがintと同じであれば問題ありませんが、intより大きい場合には動作が未定義になってしまいます。処理系のポインタ型のサイズを調べて、0と0Lを使い分けたのでは移植性が失われてしまいます。
仮にそれができたとしても、すべても問題が解決できたわけではありません。C++にはクラスメンバへのポインタがあり、通常のポインタ型より大きくなることも少なくありません。この場合には、単なる整数値を可変個実引数として渡しても、全く意味をなしません。クラスメンバへのポインタ型はC互換型(POD型)ではないからです。
結論としては、C++では可変個引数は使用しないこと、そして、関数の引数に空ポインタ定数を渡すときは明示的なキャストを行うことが有効ということです。
Trackback
http://cppemb.blog17.fc2.com/tb.php/37-72ea3b61
<< old : Next door : New >>
C++と組み込み環境 | Page Top▲
Comment