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?

有帮助吗?

解决方案

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.

许可以下: CC-BY-SA归因
scroll top