C++のswitch文

ググってC++のswitch文の説明を見ているとおよそフォールスルーが話題になりがちに見える.

#include <iostream>

int main(int argc, char** argv)
{
  switch (argc)
  {
  case 1:
    std::cout << "1." << std::endl;
    { // この波括弧は必須
      const int var(10);
      std::cout << var << std::endl;
    } // この波括弧は必須
    break;
  case 2:
    std::cout << "2." << std::endl;
    // break; // フォールスルー
  case 3:
    std::cout << "3." << std::endl;
    break;
  default:
    std::cout << "default." << std::endl;
    break;
  }
  return 0;
}

上の例で(argc==2)のケースでは"2."だけでなく"3."も表示されるというものである. だが, この機能は明らかにバグの温床になりこそすれ, 利点とはならない気がする. 要するに使うべきでではない. 調べてみるとC#では既に許されない挙動らしい. ただし, caseが連続する場合は構わないそうだ. これはまあ妥当なのかな.

http://ufcpp.net/study/csharp/st_branch.html

  case 2:
  case 3:
    std::cout << "2 or 3." << std::endl;
    break;

個人的にswitch文で引っかかったのは例の(argc==1)のようにcase以下で変数を宣言する場合の波括弧{}についてである. 上の例から波括弧を削除すると,

switch.cpp: In function ‘int main(int, char**)’:
switch.cpp:15:10: error: jump to case label [-fpermissive]
switch.cpp:12:19: error:   crosses initialization of ‘const int var’
switch.cpp:18:10: error: jump to case label [-fpermissive]
switch.cpp:12:19: error:   crosses initialization of ‘const int var’
switch.cpp:21:5: error: jump to case label [-fpermissive]
switch.cpp:12:19: error:   crosses initialization of ‘const int var’

のようなエラーがでる. これをみて初学者に何が問題かわかれというのは無理な話だろう. これはフォールスルーの原則のせいか, case文後に複数行を波括弧なしに連続して記述できるという違和感にも関連する.

ところで, case文はif文で記述することの代替として説明されることが多いように思う. 機能としては実際そのように用いると思うが, 実態としてはcase文の後の":"が示すようにgoto文のようだ. switch文の中で"goto case 3;"のようにできるようだし. 使わないけど.