|
Rule 15.7 "if...else if terminated by else" refers to "Rule 16.5". However, there appears to be a stronger relationship with 16.4: "Every switch shall have a default label". Should 16.4 be linked to 15.7?
In my opinion, there is a slight inconsistency between the rule rationale for 15.7 and 16.4 and what might be read as being covered.
Starting with Rule 15.7, the amplification requires a side-effect or a comment. Would you agree that this interpretation results in the following examples being 'non-compliant'?
Code: void f1 (int x, int y)
{
for (int i = 0; i < 10; ++i)
{
if (i % x )
{
}
else if (i % y)
{
}
else
{
break;
}
/* Non-Compliant? Not a side-effect and not a comment */
}
}
void f2 (int x, int y)
{
if (x != 0)
{
}
else if (y != 0)
{
}
else
{
return;
}
/* Non-Compliant? Not a side-effect and not a comment.
* Non-compliant to advisory 15.5 */
}
void f3 (int x, int y)
{
if (x != 0)
{
}
else if (y != 0)
{
}
else
{
;
}
/* Non-Compliant? Not a side-effect and not a comment. */
}
void f4 (int x, int y)
{
if (x != 0)
{
}
else if (y != 0)
{
}
else
{
goto END;
}
/* Non-Compliant? Not a side-effect and not a comment. */
END:
;
}
void f5 (int x, int y)
{
for (int i = 0; i < 10; ++i)
{
if (i % x)
{
}
else if (i % y)
{
}
else
{
if (i != x)
{
if (i != y)
{
if ((i*i) > (x*y))
{
}
}
}
}
/* Non-Compliant? No comment or side-effect */
}
}
And the following examples would be compliant:
Code: void f6 (int x, int y)
{
if (x != 0)
{
}
else if (y != 0)
{
}
else
{
/* Compliant */
}
}
void f7 (int x, int y)
{
if (x != 0)
{
}
else if (y != 0)
{
}
else
/* Compliant, but Non-Compliant with 15.6 */ ;
}
void f8 (int x, int y)
{
for (int i = 0; i < 10; ++i)
{
if (i % x)
{
}
else if (i % y)
{
}
else
{
if (i != x)
{
if (i != y)
{
if ((i*i) > (x*y))
{
/* Compliant? Comment "appears" in else. */
}
}
}
}
}
}
For Rule 16.4, the amplification requires a 'statement'. What do you feel is that status of the following examples?
Code: void f9 (int x)
{
switch (x)
{
case 0:
x+=1;
break;
case 1:
x+=2;
break;
case 3:
x+=3;
break;
default:
;
break;
}
/* Compliant? Is ';' a statement? */
}
void fA (int x)
{
switch (x)
{
case 0:
x+=1;
break;
case 1:
x+=2;
break;
case 3:
x+=3;
break;
default:
{ }
break;
}
/* Compliant? Depends on interpretation of 16.1 regarding { } is a compound statement */
}
void fB (int x)
{
switch (x)
{
case 0:
x+=1;
break;
case 1:
x+=2;
break;
case 3:
x+=3;
break;
default:
{ { } }
break;
}
/* Compliant? Similar to fA */
}
void fC (int x)
{
switch (x)
{
case 0:
x+=1;
break;
case 1:
x+=2;
break;
case 3:
x+=3;
break;
default:
/* Compliant */
break;
}
}
My reading of the Rationale is that the goal is have a 'defensive' comment unless the else does something, ie. the comment acts as a form of "Annotation".
Alternatively, going just from the rationale, I would mark the above functions as Compliant/Non-Compliant as follows:
- f1: Compliant
- f2: Compliant, Non-Compliant with rule 15.5.
- f3: Non-Compliant
- f4: Compliant
- f5: Compliant
- f6: Compliant
- f7: Compliant, Non-Compliant with Rule 15.6
- f8: Compliant (not because of nested comment)
- f9: Non-Compliant
- fA: Non-Compliant
- fB: Compliant
What is the view of the MISRA C group on this?
|