switch

知人が C のこんなコードを持ち出してきた。

switch(0){putchar('A');}

これは普通は実行しても文字 A は出力されないのだが、 Borland C では出力されるのだそうだ。

で、規格 (JISX3010) ではどうなっているのかと調べてみた。出力されないのが正しいようだ。要約すると「制御式の値に対応する case ラベルに跳び、対応する case ラベルが無い場合は default ラベルに跳ぶ。 対応する case ラベルも default ラベルも無ければ何もしない。」ということである。 上の例では対応する case ラベルも default ラベルも無いのであるから何もしない。 定義としては実にシンプルなもので、感覚的にも特に逸脱してはいないと思う。

規格の switch 文の記述内で興味深い例を見付けた。 以下がその例を引用したものだ。

switch(expr) {
  int i=4;
  f(i);
 case 0:
   i=17;
 default:
   printf("%d\n",i);
 }

さて、 printf は何を出力するだろうか。 結論から言えば expr が 0 の場合に 17 を出力するのを除けば不定である。 規格の中でわざわざ例まで書いているのだからハマりやすいところだと考えられているのだろう。

制御式に対応する case ラベルが無い場合には default ラベルへ跳ぶのだから i=4 は実行されず、即ち不定というわけだ。 もちろん f(i) も実行されない。 だが int i という変数の導入は有効なんである。 変数の宣言は OK で初期化は無効というのはいかにも不格好だと思う。

Document ID: 1b1335a3f0124defa04e259d6ec5991a