0

現在のコードにバグがあり、数日間頭をぶつけてきました。以下にコードの要約バージョンを投稿します(実際のコードではありませんが、コンパイルされます)。

#include <iostream>

using namespace std;

int main()
{
  int x = 7;

  switch(x)
  {
    case 1:
    {
      case 2:
      cout << "hi";
    }
  }
}

ローカル変数名が以前に使用したものと干渉しないように、スイッチケースに厳密なスコープを導入することがあります。どうやら、ある日電話で返事をしたり、思い通りにケースステートメントを書き終えなかったようですが、後で確信が持てました。ケース2は、元の外部スイッチの一部としてではなく、実際にはネストされたスイッチに含まれている必要があります(不思議に思う人のために、コードではマジックナンバーだけでなく名前付き定数を使用しています)。g ++では、オプションなしでコンパイルしても警告やエラーは発生しませんでした。

私の質問:なぜクロススコープケースがスイッチからジャンプするのを許可するのですか?それはどのような目的に役立ちますか?

4

5 に答える 5

4

Duff's Deviceは、すでに示唆されているように、クロススコープのケースラベルの「目的」ではなく、単にそれを利用したものにすぎません。

真実は、おそらくそれが意図的に設計された目的を果たしていないということですが、機能する最も単純な可能な実装のアーティファクトにすぎません。switch-case構造は、合理的なことを正確に実行できるように設計されていますが、不合理なことから明示的に保護することもありません。

于 2010-11-03T19:09:11.543 に答える
4

ケースラベルは単なるラベルであり、(コンパイラによって生成された)gotoの宛先です。

通常のラベルに関数スコープがあるのと同じように、ケースラベルにもswitchスコープがあります。

唯一の合理的な利点はDuff'sDeviceですが、これは最近のコンピューターにはあまり関係がありません。

だから、それは歴史的です。

「凍った歴史」の事例。

乾杯&hth。、

于 2010-11-03T18:58:56.177 に答える
1

そのコードは、歴史的な理由でのみコンパイルされます。

未定義動作の非常に奇妙なバージョンを引き起こす可能性があることに注意してください:

// don't try this at home
switch(x) {
  case 1:
  {
    std::string s = "hi!"
    case 2:
    cout << s; // doh!
  }
}

の場合、これは最初にコンストラクターを呼び出さずx==2にアクセスします。sとはいえ、コンパイラーはそれについて警告することを期待しています。

于 2010-11-03T19:10:03.380 に答える
1

switchステートメント内のクロススコープケースラベルは、特にリアルタイムの組み込みシステムアプリケーションで目的を果たします一つには、それらはcouroutinesのよりクリーンな実装を可能にします。また、同様の低レベルのアプリケーションでのgotoステートメントの使用を削減または排除します。はい、gotoは醜いですが、時間と同期の問題が標準である前にデバイスドライバーを作成したことがある場合は、gotoステートメントの高度なメンテナンスよりもクロススコープのケースラベルの有用性を高く評価します。あなたがそうするならば、2つの悪のうちの小さい方。

于 2013-02-25T20:40:17.747 に答える
-1

上記のコードは、次の同義語です。

switch (x)
{
     case 1:
     case 2:
     cout << "hi";
}

コンパイラーは、switch-case機能に関して、このコードと投稿したコードを区別しません。これは、手順の複数のケースシナリオとして解釈されます。

于 2010-11-03T19:00:56.617 に答える