MISRA Discussion Forums

Full Version: What operators are prohibited/allowed by rule 12.13?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
The requirement text of rule 12.13 simply states ++ and -- \"should not be mixed with other operators in an expression\", but it doesn't qualify which operators. In the supporting text, the general \"operators\" term is qualified with \"in combination with other arithmetic operators\" but doesn't specify what the \"arithmetic operators\" are.

The simple example only seems to prohibit addition { + }, which would naturally extend to { + - * / % }, and it would be reasonable to include bitwise operators { ~ & ^ | > }.

I just want to understand how restrictive this rule is.

At a minimum, you would need to permit address and indirection operators as well as structure and union member operators:
{ * & [] . -> }, where * is the unary indirection operator (not multiply), and & is the unary address operator (not bitwise AND operator).

It would also be reasonable to use relational operators { < >= }
as well as equality operators { == != }.

However, is the simple assignment operator { = } allowed?

What about compound assignment operators?
{ += -= *= /= %= &= ^= |= = }

Which of the following examples are permitted under rule 12.13?
(1) (*p)++;
(2) a[i]++;
(3) my_struct.member++;
(4) my_struct_ptr->member++;

(5) a = b++;
(6) pop_value = buffer[--index];
(7) buffer[index++] = push_value;
(8) *p1++ = *p2++;

(9) do { ... } while ((i--) > 0);

(10) sum += buffer[i++];

My thoughts:
(1) to (4) DEFINITELY allowed (just using operators to reference correct object in memory to increment/decrement).

(5) to (8) SHOULD be allowed: common to use ++ -- in \"simple\" assignments to copy data between objects.

(9) COULD be allowed: while() or do-while() loops may sometimes be preferred over for() loops.

(10) likely NOT allowed, as:
E1 = E2
is just shorthand syntax for:
E1 = E1 (E2)
for all the compound assignment operators.

So, any code using any of these (binary) operators would be discouraged:
{ + - * / % & ^ | > }

What about unary operators:
{ + - ~ }

Just for reference, QAC (6.0.1) with MISRA-C:2004 compliance module M2CM (v1.1) interprets rule 12.13 as a violation with the QAC rule:
3440 Result of ++ or -- operator used in expression.

Thus, it only allows (1) to (4), and prohibits the other forms.
Is QAC's interpretation correct? Or, are more variations allowed?

My concern is an interpretation that is too restrictive will encourage users to always take exception to the rule (i.e., disable the static analysis rule check), rather than having a rule that pinpoints examples that would likely result in a software defect (which would discourage disabling the rule).

This could be split into two rules, one that prohibits ++ and -- used with any of the following operators:
{ + - * / % ~ & ^ | > }

And another that prohibits using the result of ++ or -- operator in an expression.

This provides a two-stage filter, one that catches the more \"serious\" issue, and a more conservative filter that prohibits rather benign code.
My thoughts:
(1) to (4) allowed.

(5) to (10) Not allowed. All theses examples could be writing into several statements and without any code expansion I think (ok, depending of the compiler). Note : (8) are not allowed by MISRA Rule 17.4 (pointer arithmetic)
(1) (*p)++; /* Compliant */
(2) a[i]++; /* Compliant */
(3) my_struct.member++; /* Compliant */
(4) my_struct_ptr->member++; /* Compliant */

(5) a = b++; /* NOT Compliant */
(6) pop_value = buffer[--index]; /* NOT Compliant */
(7) buffer[index++] = push_value; /* NOT Compliant */
(8) *p1++ = *p2++; /* NOT Compliant */

(9) do { ... } while ((i--) > 0); /* NOT Compliant */

(10) sum += buffer[i++]; /* NOT Compliant */

When the increment or decrement operator is used, it shall be the only side-effect in the expression and the result shall not be used within that expression.

This will be clarified in Technical Clarification 1.