前回は最適化オプションの有無で挙動が異なるWarray-boundsオプションでした。同様に最適化オプションの有無が挙動に影響する警告オプションは他にもありました。今回のWuinitializedオプションもその一つです。未初期化の変数を使用しちゃったときに警告してくれるもの。Wallしていても最適化してなければザル。
※『オプション沼』投稿順indexはこちら
※今回は動作確認に以下を使用しています
-
- Windows11 WSL2上のUbuntu 20.04 LTS、gccのバージョンは9.4.0
-Wuninitialized オプション
今回も最適化オプションとの組みわせて挙動が変わる警告オプションです。Wuninitializedオプションです。Wallオプションの中に含まれている警告オプションであるのですが、最適化しないと何も指摘してくれません。大人の事情ね。なお、同様な未初期化のチェックをしてくれるオプションには、
Wmaybe-uninitialized
というオプションもありました。微妙に警告範囲が異なるようにも読めるのですが、今回はその差がでるような事例を実験してません。詳細については以下の御本家ドキュメントをご覧くだせーまし。
“3.8 Options to Request or Suppress Warnings”
今回実験のC言語ソース
今回のソースでは上記のドキュメントに掲載例をほぼほぼそのままで「よゐこ」はやってはいけない悪い例にしてます。ある経路では値が定まるのだけれども、ある経路では値が定まらない奴です。こんな感じ。
/* option -Wuninitialized */ #include <stdio.h> #include <stdlib.h> #include <string.h> int f1(int sel) { int x; switch (sel) { case 1: x = 1; break; case 2: x = sel+1; break; case 3: x = sel*2; break; } return x; } int main(int argc, char const *argv[]) { int result = f1(1); printf("f1(1): %d\n", result); result = f1(2); printf("f1(2): %d\n", result); result = f1(3); printf("f1(3): %d\n", result); result = f1(4); printf("f1(4): %d\n", result); return 0; }
最適化の有無による挙動の違い
さてお楽しみの最適化の有無による挙動の違いです。まずは-O0で最適化無指定です。するとこんな感じ。
Wallだろうが、Wuninitializedだろうが、Wmaybe-uninitializedだろうが、まったく警告してくれません。ダメじゃん。
つづいて最適化してみます。-O0を-O2へ変えただけ。こんな感じ。
警告が表示されております。ただ、Wallだろうが、Wuninitializedだろうが、結局、Wmaybe-uninitializedオプションによる警告として報告されとります。Wuninitializedの立場がないじゃん。
実行結果を一応確認
例によって、警告は警告でしかないので、実行オブジェクトは正常に生成されております。まず -O0 のときのオブジェクトを実行してみたところが以下に。
最後のf1(4)は未初期化変数を参照しているハズだけれど、前のf1(3)のときの結果を踏襲しているような感じっす。
警告は出てますが、実行はできます。案の定、f1(4)の結果は -O0 のときとは異なってます。未初期化変数の取り扱いの違いが見えておると。
しかし、最適化しないと効かない「ツンデレ」系オプション、意外と多いのね。