3

これは法規または規則違反になりますか?

switch (expr)
{
    do
    {
        case 6:
            /*...*/

            if (/*...*/)
                break;
        case 7:
            /*...*/

    } while (0);    

    case 9:
        /*...*/

        break;

    default:
        break;
}

これは、いくつかの条件が満たされた場合にのみ、ケース 6 に続いてケース 7 を実行する合法的な方法でしょうか? または、これにより未定義の動作が発生し、鼻のドラゴンがスイッチから出てきますか? ps私の質問はc99を参照しています。

編集:

私がやりたいことは次のとおりです。ケース9を想定し、すべてのケースで実行する必要があります。expr が 6 の場合、6 を実行する必要があり、いくつかの条件の下で 7 を実行し、その後 9 を実行するか、expr が 7 の場合は 7->9 を実行する必要があるため、いくつかの条件が満たされた場合は 7 をスキップしたいのですが、6 の順序を変更することはできません。 、7、9。

EDIT2:

別の解決策を探しているわけではありません。このスニペットの動作に興味があるだけです。

switch ステートメントに、可変に変更された型の識別子のスコープ内に関連付けられた case または default ラベルがある場合、switch ステートメント全体がその識別子のスコープ内にある必要があります。

ISO/IEC 9899:TC3 6.8.4.2->3 から

その振る舞いに不安を感じさせます。しかし、それが私のスニペットのようなコードを狙っているかどうかはわかりません。

4

3 に答える 3

1

上記のコードは有効だと思いますが、より明確にします。

case 6:
   ... 

   /* fall through */
case 7:
   if (expr != 6 || condition_to_run_7)
   {
       do whatever 7 does;
   }
   if (should_not_do_9)

case 9:
   ... 
   break;

}

または、どちらがよりクリーンな解決策です: 6、7、および 9 のケースが行うことを個々の関数に移動し、switch-statement で関連する関数を (必要に応じて複数回) 呼び出し、各ケースの後に適切な「ブレーク」を設定します。 ...

于 2013-08-13T13:58:28.830 に答える
0

はい、有効です。あなたがしたいことをしていますか?疑わしい。

入力したbreaks が唯一のものであると仮定し、コンパイラが完全な状態にならないと仮定すると (特に最適化を有効にしている場合は、率直に言って信じられないことではありません)、次のことが起こります。

case 9:: そのブロックを実行して続行し defaultます : そのブロックを実行して続行し case 7ます : そのブロックを繰り返し実行します 永久に case 6: そのブロックを実行します, おそらく 7, 永久に繰り返します

やりたいことをするには、do..while を削除し、if ブロックを の最後に配置し6ます7。場合によっては、6 または 7 のどちらのケースにいるかをチェックするためのガードを配置します。

switch (expr)
{
    case 6:
        /*...*/       
            break;
    case 7:
      if ( expr==7 || !/*...*/)
      { 
        /*...*/
      }
    case 9:
        /*...*/

        break;

    default:
        break;
}

しかし、それは私がする方法ではありません。これはおそらく、子関数にラップすることが理にかなっているものです。

void handle6() { /*...*/ }
void handle7() { /*...*/ }
void handle9() { /*...*/ }

switch (expr)
{
  case 6:
    handle6();
    if( /*...*/ ) handle7();
    handle9();
    break;
  case 7:
    handle7();
  case 9:
    handle9();
    break;
  default:
    /*...*/
}

おそらくより明確な別の方法です。

そして完全を期すために...

switch( expr )
{
    case 6:
        /*...*/
        if( /*...*/ ) goto case_9;
    case 7:
        /*...*/
    case 9:
case_9:
        /*...*/
        break;
    default:
        break;
}
于 2013-08-13T13:52:23.800 に答える