MISRA Discussion Forums

Full Version: Examples in 6.5.3 do not match definition of a loop-counter
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
A loop counter is defined as loop control variable that is, among other conditions,
Quote:© modified in expression

The examples for rule 6-5-3 state:
Code:
for (x = 0; modify(&x); ) // Non-compliant
{
}
for (x = 0; x < 10; )
{
  x = x * 2; // Non-compliant
}
But in both cases x is not a loop counter due to condition © being not satisfied (the expression is empty, no modification of x here), and thus the rule's text is not violated.
Should the examples be changed to contain a ++x in the expression?
You are correct to say that the non-compliant loops do not have a loop counter to modify.

The two loops concerned should have ++x added as the third expression to the loop. This correction will be included in a technical update to the document.

Thank you for bringing this to our attention.
I am not sure I can agree concerning the second loop in the code example. The fact that the loop counter was not one according to the definition and therefore the rule was not violated is in my opinion the wrong way to look at it.

Rather the opposite: x is clearly used (and recognised by the reader) like a standard loop counter: it is initialised in the first and used for the condition in the second field, only the programmer wanted some trickier modifiation and put it somewhere else. So what makes the code non-compliant is not that x was not a loop counter, but that its modificator is not placed in expression as it should be.

It can be assumed that the programmer probably wanted to have *2 the only modifications of x, so "correcting" the code examples by adding an extra ++x would blur the focus of the problem. The question is: should the second loop be valid in the sense of error avoidance?


Concerning the first loop, it can be argued whether this should be a valid for-loop or not according to 6.5.3: adding an extra ++x would render modify() as a second modificator of x, but even then x would strictly spoken not be a loop counter by definition since condition does not use a relational operator (item b). According to this argumentation, this would still be not a violation of 6.5.3:
Code:
for ( x = 0; modify ( &x ); ++x )

This brings me back to the consideration that x might still be seen as the loop counter, but I would not insist, since if not, rule 6-5-1 would kick in.
The official response seems reasonable to me - it has been given to us by the team that wrote the rule and they are simply clarifying the intent of the rule.

Think about it from the point of view of trying to check the code (with a tool). A tool will have to look for patterns within the code to try and identifiy when a loop is non-compliant. The C++ Standard does not define "loop counters". It may be "obvious" to a programmer what a loop counter is, but a formal specification is needed if tools are going to have a consistent interpretation of what is (or is not) a loop counter. The introductory text before 6-5-1 provides such a specification. The examples in 6-5-3 do not meet the criteria given and therefore do not have loop counters, even if the second example does have something "like a loop counter".

You say that "... only the programmer wanted some trickier modifiation and put it somewhere else". That is a good point and it highlights why the rules exist - they restrict the complexity that is acceptable for a loop without the use of a deviation.
Yes, I understand that it is hard for automatic tools to figure out what is going on when definitions are not exact, and that my view would introduce such blurriness here.
I firstly read the rule from a human standpoint, and in a code review, I would ask: "Why don't you modify your loop counter in expression?".

Nevertheless, I am happy with the other view as well. Let's see the options:
  • x is considered a loop counter. Then it is modified elsewhere, so rule 6-5-3 applies.
  • x is not a loop counter. Then rule 6-5-1 applies which requests one.
  • ++x is amended in expression, so x becomes a loop counter and the first case applies. So it fixes the code example ;-)
-> Result: x=x*2 would be considered as non-compliant in any case.


---
The second point I objected, however, is that adding ++x to the first loop, as it was proposed, still does not make a valid example for 6-5-3, because the return value of modify() is boolean. Unless the inner logic of modify() is seen sufficient to satisfy the requirement of a relational operator.
You are correct. "++x" should be added as the third expression in these loops.