15

MISRA 14.5は、continueステートメントを使用してはならないと述べています。誰かが理由を説明できますか?ありがとうございました。

4

4 に答える 4

24

それは、無条件の分岐とスパゲッティコードについての古代の議論gotoのためであり、それは40年ほど続いています。goto、、および複数のステートメントはすべてcontinue、多かれ少なかれ同等に悪いと見なされます。breakreturn

世界のプログラミングコミュニティのコンセンサスは、大まかに次のようなものになりました。自分が何をしているのかを知っていれば、スパゲッティコードを書かなくても言語のこれらの機能を使用できることを認識しています。しかし、彼らが何をしているのかわからない人が、機能が利用可能であればそれを使用してスパゲッティを作成する可能性が高いため、私たちはまだそれらをお勧めしません。また、それらは不要な機能であるため、お勧めしません。明らかに、それらを使用せずにプログラムを作成できます。

MISRA-Cは重要なシステムを対象としているため、MISRA-C:2004には、これらの無条件のブランチ機能を可能な限り禁止するアプローチがあります。したがって、、gotoおよびcontinue複数の返品は禁止されました。break同じループ内に1つのブレークがあった場合にのみ許可されました。

ただし、現在評価中の「MISRA-C:2011」ドラフトでは、委員会はこれらすべての機能を再度許可することを検討しましたが、gotoは下方向にのみジャンプし、上方向にはジャンプできないという制限があります。委員会の論理的根拠は、悪いプログラムフローを見つけるのに十分スマートなツール(つまり静的アナライザー)があるので、キーワードを許可できると述べました。

後藤論争はまだ続いています...

于 2012-06-12T11:18:24.693 に答える
5

Cでプログラミングすると、複数の実行ブランチを追跡するのが難しくなることで有名です。リソースをどこかに割り当てる場合は、ローカル以外の場所でリソースを解放する必要があります。コードが分岐する場合は、通常、分岐ごとに個別の割り当て解除ロジックまたはスコープを終了する方法が必要になります。

このcontinueステートメントは、ループのスコープから抜け出すための別の方法を追加しforます。したがって、そのようなループを推論し、制御がループを流れる可能性のあるすべての方法を理解するのが難しくなり、コードが動作することを確認するのが難しくなります。すべての状況で正しく。

これは私の側の単なる推測ですが、この余分な分岐動作から生じる複雑さを制限しようとすることが、あなたが言及するルールの推進的な理由であると思います。

于 2012-06-11T07:13:48.860 に答える
4

私はちょうどそれに遭遇しました。アイテムがあります

  • いくつかのことをチェックする必要があります、
  • チェックにはいくつかの準備が必要です、
  • 最初に安価な小切手を適用してから、高価な小切手を適用する必要があります。
  • 一部のチェックは他のチェックに依存します、
  • チェックに失敗したアイテムはどれでも、ログに記録する必要があります。
  • アイテムがすべてのチェックに合格した場合、それはさらなる処理に渡される必要があります。

続行せずにこれを見てください:

foreach (items) {

   prepare check1
   if (check1) {

      prepare check2
      if (check2) {

        prepare check3
        if (check3) {
          log("all checks passed")
          process_good_item(item)
        } else {
          log("check3 failed")
        }

      } else {
        log("check2 failed")
      }

   } else {
      log("check 1 failed")
   }    
}

...そしてこれと比較して、続行します:

foreach (items) {

   prepare check1
   if (!check1) {
      log("check 1 failed")
      continue
   }

   prepare check2
   if (!check2) {
      log("check 2 failed")
      continue
   }

   prepare check3
   if (!check3) {
      log("check 3 failed")
      continue
   }

   log("all checks passed")
   process_good_item(item)
}

「prepare」-sはそれぞれ複数行の長さであるため、コード全体を一度に表示することはできないと想定します。

自分で決めてください

  • 複雑さが軽減され、実行グラフがシンプルになります
  • 循環的複雑度の値が低い
  • より読みやすく、より直線的で、「アイジャンプ」がありません
  • より拡張性が高い(たとえば、check4、check5、check12を追加してみてください)

IMHOミスラはこのトピックでは間違っています。

于 2020-04-20T16:26:48.240 に答える
1

すべてのMISRAルールと同様に、それを正当化できる場合は、ルールから逸脱することができます(MISRA-C:2004のセクション4.3.2)

MISRA(および他の同様のガイドライン)の背後にあるポイントは、一般的に問題を引き起こすものをトラップすることです...はい、continue適切に使用できますが、証拠はそれが問題の一般的な原因であることを示唆しました。

そのため、MISRAはその(乱用)使用を防ぐためのルールを作成し、レビューコミュニティはそのルールを承認しました。そして、ユーザーコミュニティの見解は、一般的にルールを支持しています。

しかし、繰り返しますが、もしあなたが本当にそれを使いたいのなら、そしてあなたはそれをあなたの会社の階層に正当化することができます、逸脱してください。

于 2012-09-27T09:49:59.350 に答える