オプション沼(22) gcc、Wnull-dereference、最適化しないと効かない3

Joseph Halfmoon

前回前々回と最適化をかけた時だけ働いてくれる警告オプションを見ました。最適化の副産物として、ついでにチェックしてやるみたいな。大人の事情ね。ちょっと興味をもって調べてみたら、そういうオプションまだまだあるみたいっす。今回のWnull-dereferenceもそういうオプションのひとつであります。

※『オプション沼』投稿順indexはこちら

※今回は動作確認に以下を使用しています

    • Windows11 WSL2上のUbuntu 20.04 LTS、gccのバージョンは9.4.0
-Wnull-dereference オプション

このオプションは長いそのお名前のとおり、NULLポインタの指す先をデリファレンスするような不埒な操作を検出し、警鐘を鳴らしてくれるオプションであります。そんなことは決してしない立派なプログラマの方々には不要かとも存じますが、あっちゃこっちゃにポインタを渡しているうちにNULLなんだかどうなんだかわけわからなくなってくるこの年寄のようなものには有効なチェックかと。詳しくは、御本家ドキュメントをご覧くだせーまし。

3.8 Options to Request or Suppress Warnings

今回実験のC言語ソース

アカラサマにNULLポインタをデリファレンスするという無体なことをするだけのコードなので以下のように短いコードです。一応、比較のため、正常にデリファレンスできることをやった後に、アカラサマなNULLしてます。

/* option -Wnull-dereference */
#include <stdio.h>
#include <stdlib.h>

int f1(int* ptr) {
    return *ptr;
}

int main(int argc, char const *argv[])
{
    int result = 333;
    int* ptr = NULL;
    printf("f1(&result): %d\n", f1(&result));
    printf("f1(ptr): %d\n", f1(ptr)); // will cause segmentation fault.
    return 0;
}な

なお、ポインタにNULLを突っ込まず、放置した状態で-O2 -Wallすると、前回やった -Wuninitialized の警告の方に先に引っかかります。

最適化の有無による挙動の違い

さてお楽しみ。最適化の有無による挙動の違いが以下に。Wnull_defreference

どちらも -Wnull-dereference しているのに -O2 と組み合わせたものは警告が出るのに、-O0の方はザルです。

「見なくもない」実行結果、念のため

生成されたオブジェクトの実行結果など、見たくもありませんが、念のため実行してみると以下のとおり。Segmentation faultとな。ExecResult

Segmentation faultで落ちると、自分のお馬鹿加減に呆れるというか、不甲斐なさをヒシヒシと感じますです。まあ、今回はテスト用のコードだからダメージないどころか、予定通りフォルトでよかったケド。

オプション沼(21) gcc、‐Wuninitizlized、最適化のときだけ働く、その2 へ戻る

オプション沼(23) gcc、dangling-pointerの見つけ方、伝統的な方? へ進む