3

For a safety-critical domain, with a code standard including the MISRA C 2004 guidelines, a "simple" piece of code becomes obtuse, chiefly because of the requirements both that all if() statements have an else and that there is only 1 return per function, and 1 break per loop. The original code looked like this:

while (bIncrementalOperation(&data)) { vCode; if (bCondition1) { u16Status |= u16STATUS_N1; break; } if (bCondition2) { u8Var++; } if (bCondition3) { u16Status |= u16STATUS_N2; break; } if (bCondition4) { break; } if (bCondition5) { vCode; } else { if (bCondition6) { break; } } vCode; } 

Which is long because of formatting, but fairly terse. In comparison, to attempt compliance, it becomes:

bContinue = TRUE; while (bContinue) { bContinue = bIncrementalOperation(&data); if (!bContinue) { /* Normal exit condition: ... */ } else { bContinue = bCondition1; if (!bContinue) { u16Status |= u16STATUS_N1; } else { u8Var += (bCondition2) ? 1U : 0U; bContinue = (bCondition3); if (!bContinue) { u16Status |= u16STATUS_N2; } else { bContinue = bCondition4; if (!bContinue) { /* Normal exit condition: .... */ } else { if (bCondition5) { vCode; } else if (bCondition6) { /* Normal exit condition: ... */ break; } else { /* Continue to do IncrementalOperation */ } vCode; } } } } } 

This pattern occurs often, especially in guarding functions which test against multiple failure modes, which leads to bugs. Is there a better pattern, that does not break the MISRA requirements?

2
  • 2
    Possible duplicate of How to tackle a 'branched' arrow head anti-pattern? Commented Oct 31, 2019 at 18:57
  • 4
    While perhaps a duplicate question, without context, all the answers point to the optimal pattern: use multiple returns/breaks. With MISRA C, none of those answers give a valid pattern. Commented Oct 31, 2019 at 18:58

1 Answer 1

10

Upgrade to MISRA C:2012.

MISRA C:2012 does not contain Required Rule 14.9: "An if(expression) construct must be followed by a compound statement." or Required Rule 14.10: "All if/elseif must be terminated with an 'else' clause."

Problem solved.

Rule 15.5: "A function should have a single point of exit at the end" is Advisory, not Required. The primary motivation for a single exit point is to make it easier to get manual memory management correct; if your function doesn't allocate memory, you probably don't need it.


Note that you're probably reading MISRA C:2004 Rule 14.10 wrong. It only applies to else if statements:

This rule applies whenever an if statement is followed by one or more else if statements; the final else if shall be followed by an else statement. In the case of a simple if statement then the else statement need not be included.

The requirement for a final else statement is defensive programming. The else statement shall either take appropriate action or contain a suitable comment as to why no action is taken. This is consistent with the requirement to have a final default clause in a switch statement.

MISRA C:2004 Rule 14.9 can be read as "Always use braces with if statements," which is still good advice today.

3
  • 1
    Seeing the braindead code which I tried to construct following the stated rules, just to learn there are more MISRA nonsense rules invalidating my attempts, I guess this is definitely the best solution (+1). Commented Oct 31, 2019 at 20:14
  • 2
    MISRA C:2004 is very old. I would imagine that the newer standard applies many lessons learned. Commented Oct 31, 2019 at 20:15
  • 1
    Thank you for the clarity! The company code standard, incorporating MISRA, hasn't been changed since long before 2012. Commented Oct 31, 2019 at 21:09

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.