为什么“继续”在MISRA C:2004中被视为C违规?

时间:2012-06-11 07:04:09

标签: c misra

MISRA 14.5表示不得使用继续声明。任何人都可以解释原因吗? 谢谢。

4 个答案:

答案 0 :(得分:19)

这是因为ancient debate about goto,无条件分支和意大利面条代码,已经持续了40年左右。 gotocontinuebreak和多个return语句都被认为或多或少同样糟糕。

世界编程界的共识大致结束了这样的事情:我们认识到,如果你知道自己在做什么,就可以使用这些语言的功能,而无需编写意大利面条代码。但是我们仍然不鼓励他们,因为很有可能一个不知道他们正在做什么的人如果可以使用这些功能,然后创建意大利面。我们也不鼓励他们,因为它们是多余的功能:显然你可以在不使用它们的情况下编写程序。

由于MISRA-C针对的是关键系统,因此MISRA-C:2004可以采用尽可能多的禁用无条件分支功能的方法。因此,gotocontinue和多个退货被禁止。只有在同一循环中有一次中断时才允许break

然而,在目前正在评估的“MISRA-C:2011”草案中,委员会已考虑再次允许所有这些功能,并限制只允许goto向下跳,永不向上。该委员会的理由说,现在有工具(即静态分析仪)足够聪明,可以发现不良的程序流,因此可以允许关键字。

goto辩论仍然很强烈......

答案 1 :(得分:5)

用C编程使得跟踪多个执行分支变得非常困难。如果您在某处分配资源,则必须在其他位置(非本地)释放它们。如果您的代码分支,您通常需要为每个分支或退出范围的方式分别设置释放逻辑。

continue语句添加了另一种退出for循环范围的方法,因此使得这样的循环更难以推理和理解控制可以通过它的所有可能方式这反过来又使你很难确定你的代码在所有情况下都能正常运行。

这只是我的猜测,但我认为试图限制来自这种额外分支行为的复杂性是你提到的规则的驱动原因。

答案 2 :(得分:1)

与所有MISRA规则一样,如果你可以证明这一点,你可以偏离规则(MISRA-C:2004第4.3.2节)

MISRA(以及其他类似指南)背后的要点是捕捉通常会导致问题的事情......是的,continue可以正确使用,但证据表明这是问题的常见原因。

因此,MISRA制定了一项规则来防止其(ab)使用,审查社区批准了该规则。用户社区的观点通常支持该规则。

但我再说一遍,如果你真的想要使用它,并且你可以证明它适用于你的公司层级,那就偏离。

答案 3 :(得分:1)

我刚碰到它。我们有

  • 应该检查几件事,
  • 检查需要一些准备,
  • 我们应该首先应用廉价的支票,然后再使用昂贵的支票,
  • 某些支票取决于其他人
  • 无论哪一项检查失败,都应记录下来,
  • 如果该项目通过了所有检查,则应将其传递给进一步处理。

观看此视频,无需继续

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 Misra在这个主题上是错误的。