とある(比較的広く使われている)C言語のプログラムをデバッグしていたのだけれど、なんか初期化されていない変数を使っていそうな感じの箇所が多い。
そこで、全体をgcc -Wmaybe-uninitialized
でチェックしてみると、結構出てきた。
(デバッグの話はこれで終わり。)
もっとも、maybeだけあって、必ず妥当な警告を出すわけではなくて、
void *ptr;
if (cond) {
ptr = hoge_alloc();
*ptr = ...
}
...
if (cond)
hoge_free(ptr);
みたいなコードでcond
が変化しない場合、特に問題は起きないはずだけれど、「初期化してないかもしれない変数ptr
を使っている」と警告を出してしまう。
でもこれって、そういうのに引っかからないように、例えば
void *ptr = NULL;
if (cond) {
ptr = hoge_alloc();
*ptr = ...
}
...
if (ptr != NULL)
hoge_free(ptr);
みたいにした方が変なバグ入り込みにくいんじゃないかね?
よくある「hoge_free(NULL)
は何もしない」って仕様だったら後半のif
も不要。
で、恐ろしいのは、
uid_t uid;
if (name != NULL) {
pwd = getpwnam(name);
...
uid = pwd->uid;
}
...
if (setuid(uid) < 0) {
...
}
みたいなやつで、uid
に変な値が入っててもアレだけど、普通に0で初期化されているともっと「やばいですね!」(プリコネR風に)
uid
の初期値をnobody的な値にしておいてもいいかもしれないけど、
uid_t uid;
if (name == NULL)
return ERROR;
pwd = getpwnam(name);
...
uid = pwd->uid;
...
if (setuid(uid) < 0) {
...
}
とか、最初から-Wmaybe-uninitialized
に引っかからないような書き方に改めた方が(≒if
文の中で初期化して外で使うのをやめた方が)良い気がする。
(気がするというか、当然そうするもんだと思ってたけど、意外にそうでないコードが多いようで。)