Why "continue" is considered as a C violation in MISRA C:2004?
Asked Answered
S

4

16

Why does MISRA 14.5 say that the continue statement must not be used?

Streamlet answered 11/6, 2012 at 7:4 Comment(2)
Have you asked them for their reason?Oblation
As with all the "always" and "never" rules, they probably aren't worth much attention.Ahab
R
26

It is because of the ancient debate about goto, unconditional branching and spaghetti code, that has been going on for 40 years or so. goto, continue, break and multiple return statements are all considered more or less equally bad.

The consensus of the world's programming community has roughly ended up something like: we recognize that you can use these features of the language without writing spaghetti code if you know what you are doing. But we still discourage them because there is a large chance that someone who doesn't know what they are doing are going to use the features if they are available, and then create spaghetti. And we also discourage them because they are superfluous features: you can obviously write programs without using them.

Since MISRA-C is aimed towards critical systems, MISRA-C:2004 has the approach to ban as many of these unconditional branch features as possible. Therefore, goto, continue and multiple returns were banned. break was only allowed if there was a single break inside the same loop.

However, in the "MISRA-C:2011" draft which is currently under evaluation, the committee has considered to allow all these features yet again, with a restriction that goto should only be allowed to jump downwards and never upwards. The rationale from the committee said that there are now tools (ie static analysers) smart enough to spot bad program flow, so the keywords can be allowed.

The goto debate is still going strong...

Resort answered 12/6, 2012 at 11:18 Comment(2)
Does anybody know if this rule was left out of MISRA-C:2012?Trenatrenail
@Trenatrenail It is still there but relaxed from Required to Advisory (rule 15.1). When I wrote this old answer, the 2012 version wasn't official yet. There are also additional Required rules for how you are allowed to use goto if you use it in your program. The single break rule is still there but relaxed to Advisory. The rule against continue was removed. The single return rule was relaxed to Advisory.Resort
O
5

Programming in C makes it notoriously hard to keep track of multiple execution branches. If you allocate resources somewhere, you have to release them elsewhere, non-locally. If your code branches, you will in general need to have separate deallocation logic for each branch or way to exit a scope.

The continue statement adds another way to exit from the scope of a for loop, and thus makes such a loop harder to reason about and understand all the possible ways in which control can flow through it, which in turn makes it harder to ascertain that your code behaves correctly in all circumstances.

This is just speculation on my part, but I imagine that trying to limit complexity coming from this extra branching behaviour is the driving reason for the rule that you mention.

Oblation answered 11/6, 2012 at 7:13 Comment(6)
IMO, if continue makes a loop hard to understand, then the loop code is too long....Detached
@MitchWheat: Yeah. You should lobby MISRA to add a "no long loops" rule! (But personally, in C++, I find it very hand say to be able to skip comment lines when parsing input with a simple continue. Then again, C++ is a much more suitable language for the "early exit" idiom.)Oblation
Pointless: From experience, coding standards like their's are often dumbed down for the lowest common denominator. I use continue in C/C++/C# It is a perfectly good construct.Detached
@MitchWheat: And understandably so. It's much more economical to test a large codebase for a simple rule than to get an expert consult on every single instance where a programmer was "clever enough" to write correct code. It's a classical trade-off. It may be unpleasant for the clever programmer, but in the big picture it's possible that that's the most productive solution...Oblation
Actually, I think its better to write tests....I'm certainly not advocating that terse 'clever' code is good. Far from it. I prefer simple clean code. The point I was trying (poorly) to make is that saying you can't use 'continue' or 'break' is not productive, and may in fact lead to 'dirtier' code. It's treating the symptoms and not the cause.Detached
I found a piece of answer from MISRA Bullet Board: MISRA C Steering " In writing MISRA-C:2004, the use of a loop with two exits was considered acceptable. One is available for normal exit, and the second for exceptional exits". continue makes loop's logic complex because it changes the logic inside loop body.Streamlet
W
5

I've just run into it. We have items, which

  • should be checked for several things,
  • checks require some preparation,
  • we should apply cheap checks first, then go with expensive ones,
  • some checks depends others,
  • whichever item fails on any check, it should be logged,
  • if the item passes all the checks, it should be passed to further processing.

Watch this, without continue:

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")
   }    
}

...and compare with this, with continue:

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)
}

Assume that "prepare"-s are multiple line long each, so you can't see the whole code at once.

Decide yourself, which is

  • less complex, have a simpler execution graph
  • have lower cyclomatic complexity value
  • more readable, more linear, no "eye jumps"
  • better expandable (e.g. try to add check4, check5, check12)

IMHO Misra is wrong in this topic.

Winton answered 20/4, 2020 at 16:26 Comment(0)
C
2

As with all MISRA rules, if you can justify it, you can deviate from the rule (section 4.3.2 of MISRA-C:2004)

The point behind MISRA (and other similar guidelines) is to trap the things that generally cause problems... yes, continue can be used properly, but the evidence suggested that it was a common cause of problem.

As such, MISRA created a rule to prevent its (ab)use, and the reviewing community approved the rule. And the views of the user community are generally supportive of the rule.

But I repeat, if you really want to use it, and you can justify it to your company hierarchy, deviate.

Cb answered 27/9, 2012 at 9:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.