3

I have a question related to MISRA 2012 Rule 14.2 "A for loop shall be well-formed"

Conside below sample code :

int foo (int *ptr)
{
    (*ptr)--;
     return *ptr;
}

void main()
{
    int a =20;
    int i;
    for (i=0; i< foo(&a) ; i++)
    {
         /*
         <loop body>
         */       
    }
}

Here for line for (i=0; i< foo(&a) ; i++) I am getting a MISRA violation, 14.2. The question is when we modify the variable (a) present in the loop condition (i< foo(&a)), in a function like shown. is it valid violation ?

Its just a sample case, for 14.2, Please do not focus on the loop being infinite in the above sample code.


14.2 Rule : Second clause which
- Shall be an expression that has no persistent side effects, and
- Shall use the loop counter and optionally loop control flags, and
- Shall not use any other object that is modified in the for loop body.

Example :-

 bool_t flag = false;
    for ( int16_t i = 0; ( i < 5 ) && !flag; i++ )
    {
    if ( C )
    {
    flag = true; /* Compliant - allows early termination
    * of loop */
    }
    i = i + 3; /* Non-compliant - altering the loop
    * counter */
    }

Prashant Singh
  • 101
  • 2
  • 9
  • 1
    Are you saying that the shown code is not an infinite loop? You would have to initialise `a` in order to be sure. But it is either an infinite loop or will never loop even once. – Yunnosch Jun 05 '18 at 03:38
  • @Yunnosch : thank you for comment, noted the same – Prashant Singh Jun 05 '18 at 03:43
  • You reacted to the second comment, the first one did not convince you? – Yunnosch Jun 05 '18 at 03:44
  • There is of course the case of undefined behaviour because of integer overflow, but that is not what you are relying on, is it? – Yunnosch Jun 05 '18 at 03:45
  • @Yunnosch : the question is when we modify the variable present in the loop condition, in a function like shown. it is a violation. I am saying the above code is an infinite loop, howerver I m just concerned about the MISRA violation, as its a sample case only – Prashant Singh Jun 05 '18 at 03:45
  • 1
    What I am trying to say is that you should improve your [mcve] in order to help people focus on the actual question. The shown code will cause the kind of clarification question comments I have demonstrated. – Yunnosch Jun 05 '18 at 03:46
  • Can you provide a full quote of MISRA 14.2, including explanation and examples? I do not have access (now) and assume that is the case for many users which would otherwise be willing to help. – Yunnosch Jun 05 '18 at 03:48
  • Are you sure about the quote? Here https://doc.hcc-embedded.com/display/CODING/MISRA+Rules it says "14.2 All non-null statements shall either have at least one side effect however executed, or cause control flow to change." Your code is more consistent with the shown code, but you probably need to avoid confusion. – Yunnosch Jun 05 '18 at 03:51
  • yes I am sure, for MISRA 2012, sry could not share the complete doc, however added details as per MISRA, for for-loop`s second part (conditional part) – Prashant Singh Jun 05 '18 at 03:56
  • Please elaborate what you mean by "where its clear that it is an infinite loop". – Yunnosch Jun 05 '18 at 04:00
  • 1
    For a less distracting MCVE (while keeping its example function, I hope) I recommend to init `a=20;` and change the function body to `(*ptr)--; return *ptr;` – Yunnosch Jun 05 '18 at 04:12
  • In addition, `int a` and `(*ptr)--;` are both MISRA violations. `void main()` is obsolete style as per the C standard, you should be using `void main (void)` or equivalent implementation-defined format. – Lundin Jun 05 '18 at 06:35
  • Is there any reason you cannot do `int b = foo(&a); for (i=0; i – Andrew Jun 14 '18 at 08:59

2 Answers2

5

Your example code violates the quoted rule (first bullet) because
it does have side effects (or the compiler cannot really tell, because of calling a function with a prototype which would allow such side effects - and happens to have at least one).

Your example might violate the quoted rule (third bullet) if the (side-) effects of the loop continuation condition (i< foo(&a)) are counted (by your specific MISRA analyser) as part of "the loop body". (I would not, but your tool might.)

So your shown code violates the rule between one and two times.

Yunnosch
  • 26,130
  • 9
  • 42
  • 54
0

The rationale for Rule 14.2 shows that this Rule is intended to restrict for loops, stopping "clever" uses, and thus make code easier to review and analyse...

I have a simple maxim:

  • If you have a pre-determinable number of iterations, use a for loop
  • If you don't have a pre-determinable number of iterations, use a while ... do loop

Assuming foo(&a) is does not return a constant, you would be better off using a while ... do loop:

int a = 20;
int i = 0;

while ( i < foo(&a) )
{
  // Loop body
  ...
  ++i;
}

Note: See profile for disclaimer.

Andrew
  • 2,046
  • 1
  • 24
  • 37