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?