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
    Possible duplicate of How to tackle a 'branched' arrow head anti-pattern? – gnat Oct 31 '19 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. – JWCS Oct 31 '19 at 18:58
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.

| improve this answer | |
  • 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). – Doc Brown Oct 31 '19 at 20:14
  • 2
    MISRA C:2004 is very old. I would imagine that the newer standard applies many lessons learned. – Robert Harvey Oct 31 '19 at 20:15
  • 1
    Thank you for the clarity! The company code standard, incorporating MISRA, hasn't been changed since long before 2012. – JWCS Oct 31 '19 at 21:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.