お世話様です。
今までポインタは何でもかんでもNULLで初期化していたのですが
以下のURLを読むと関数ポインタにNULLを代入するのは
あまり良くないように書かれています。
http://portable-c.jugem.jp/?eid=22
仕事ではCで組込系のプログラムを作っていますが、
移植性を考えるとNULLではなくて0を代入するべきなんでしょうか。
「初期化」とは 0 にすることでも NULL にすることでもなくて
「適切な値にすること」
であるわけだから、そもそものスタート時点で話が間違ってる
char* p=0; /* or NULL */
p=malloc(1000);
なんて書いてあるソースコードがあったら、俺なら書き直させるレベル
んで 0 と NULL のどちらがより適切かということなら、それは立場次第かなぁ
俺は最近 C ではなく C++ でソース書いている関係で 0 を使う
今後 C++ でソース書く可能性があるなら 0 のほうが適切かもしれない
どのみちお使いの処理系での NULL の定義が #define NULL 0 であるならば
(void*)0 問題は生じないわけでどーでもいい。
そもそも提示リンク先は JIS X 3010:2003 で話をしているわけだが。
とりあえず JIS X 3010-1993 の 6.2.2.3 には「代入できる」とある。
tetrapodさん
お返事ありがとうございます。
> スタート時点で話が間違っている
そうですね。すみません。
まず「初期化」という用語が間違いでした。初期化というよりは
「関数ポインタに対してヌルポインタの代入もしくは
ヌルポインタによる初期化をしたい場合、NULLと0のどちらが適切か?」
というのをお聞きしたかった次第です。
>今後 C++ でソース書く可能性があるなら 0 のほうが適切かもしれない
うちの職場でC++に移行することは当面なさそうですね…。
(仕事の効率化のために自作でWin32アプリを作ることもありますが)
> どのみちお使いの処理系での NULL の定義が #define NULL 0 であるならば
0だったり(void*)0だったりしますね。
俺も組み込み系で SH* とか H8* とか AR* とか使っているわけだけど
C++ に移行しているよ (template バリバリ)
そのへんはさておき、組み込み系で使われている多くの C コンパイラは
その仕様として、国際規格書 (プログラミング言語 - C) ISO/IEC 9899:1989
日本では JIS X 3010-1993
いわゆる C89 をベースにしているものがほとんどで、
リンク先で議論している X 3010:2003 (C99) に基づいているものはほとんどない
というのが現状になるわけだ
そして X3010-1993 は
・空ポインタ定数とは 0 または (void*)0 である
・空ポインタ定数を関数へのポインタ変数に代入できる
・空ポインタ定数は、どの実体へのポインタ右辺値とも一致しない
と主張しているわけだ (こういう話に興味があるなら、規格書を買ってくれ)
なので疑問点「NULLと0のどちらが適切か」に対する答えは
「どちらも同じだけ適切」となる。どっちでも問題ないよ
俺なら C++ コンパイラに掛ける関係で 0 を使うけどさ
移植性の問題なら、私はNULLにするかな。
無理に0(組込型)だけでなんとかせずに、環境に合わせて再定義する方がスマー
トな気がするから。
(例)
#ifdef WIN32
#define NULL 0
#else
#define NULL (void*)0
#endif
>>> tetrapodさん
私も組込みの仕事でC++を使いたいんですけど、
会社がOKしてくれません…。説得するのも大変ですし。
そもそもまともにC++を使えるPGがほとんど居ない気がします…。
>規格書
私はJIS X 3010:2003しかもってないです。
会社が買ってくれないんですよね…。とほほ。
> 「どちらも同じだけ適切」
なるほど、よくわかりました。
明快な回答ありがとうございました。
とりあえず他のポインタ同様にNULLを使おうと思います。
というわけでひとまず「解決」とします。
>>> bunさん
NULLを再定義ですか…。
個人的には処理系で定義されているものを
自分で再定義するのはイヤですね。