MISRA Discussion Forums

Full Version: Rule 12.2: Accessing volatiles in simple assignment statemnt
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi!

It is stated in the MISRA-C:2004 rule 12.2 (required) that "...it is recommended that volatiles only be accessed in simple assignment statements, such as the following:"
Code:
volatile uint16_t v;
/* ... */
x = v;
Is this recommendation a part of the MISRA-C:2004 12.2 rule, or is it just a common recommendation?
Should a MISRA-C:2004 analysis tool try to enforce this kind of assignment statement?

Is the following statement part of the "simple assignment statements" philosophy (I think so)?
Code:
volatile uint32_t *v = AN_ADDRESS;
/* ... */
*v = x;

The reason for this question is that our current analysis tool raises a MISRA-C:12.2 violation for the last code snippet above, and I think this is a misinterpretation of the guidelines.

//JOA
That depends on where the volatile variable is allocated. If it is allocated as a local variable (automatic storage duration), then there shouldn't be any risk with that line.
If it is allocated as a global/static variable (static storage duration), the variable is initalized in the beginning of the program only, and then you have created a potential hazard.

A parenthesis:
In my opinion, there is never a reason to initialize variables on the declaration line in the C language. This is only necessary in C++, because of constructors. Instead, use runtime assignment. Avoiding initialization of objects with static storage duration only makes your program faster (less startup copy-down code) and safer (no time delay between initalization and usage). And there are no setbacks. Initalization is yet another useless, redundant functionality in the C language.
The MISRA rule contains a recommendation that volatile objects should only be accessed in simple assignment statements. It is a generally recommended but it is not an essential part of the rule.

It is possible that some static analysis tools will implement the recommended check but it is not essential that a tool should do so.

The example in which a pointer to a volatile object is dereferenced should be treated as a "simple assignment" in that it is not a compound assignment, and there is no ambiguity possible in this expression provided that *v and x denote distinct objects.
Can you tell me which analysis tool you are using?
Just another question on the volatile variables in this rule, as I am implementing the MISRA C 2004 rules for a static analyser (www.frama-c.com). If I interpret the rule literally I have the following:

volatile int v=4;
int x=5;

v+=3; // Not compliant
v=x; // Compliant
x=x+v; // Compliant
x+=v; // Not compliant
x=v+v; // Compliant

Is this correct?
Shouldn't the last assignment be NOT compliant as its rhs causes a side effect?
The example:
Code:
x = v + v;
is strictly-speaking compliant with the rule. There are two read accesses of v, each of which will cause a side-effect, but because the + operator is commutative it doesn't matter in which order the two operands are evaluated in this case.

If the example were:
Code:
x = v - v;
then this would be non-compliant because the value of the expression will depend on the order in which the v operands are evaluated, unless they both evaluate to the same value.

It is also worth noting that:
Code:
x = v1 + v2;        // v1 and v2 both volatile
would be non compliant because the value of v1 might be affected by the evaluation of v2 and vice-versa. Any side-effects arising from the evaluation of v1 might be affected by the evaluation of v2 and vice-versa. The order in which any side-effects arising from evaluation of v1 and v2 would depend on the order in which they were evaluated and this might be observable, for example if v1 and v2 are I/O ports.

Having said all that, the rule does contain the recommendation that volatile objects are accessed only in simple assignments such as:
Code:
x = v;
to ensure that a sequence point occurs between each evaluation of a volatile object. Checking tools are not expected to implement recommendations, but they may do so if they wish. If the recommendation is checked then both of:
Code:
x = x + v;
x = v + v;
are non-compliant
I understand the idea behind the evaluation of several volatile variables done in an assignent statement, namely that reading one of them may cause a side-effect on another (volatile or non volatile) variable or on itself.

However they are all using simple assignments (in the sense ISO §6.5.16.1).
To be very precise about the rule to be implemented: any simple assignment that involves a volatile variable should be of the form x = v; with only the volatile variable on the rhs expression. Therefore x=v+1; is (strictly speaking) non compliant.
The rule requires that the expression should be guaranteed to have the same value regardless of the order in which the operands within the expression are evaluated. This usually means no more than one volatile access occuring in the expression. All of the examples given in your original posting are compliant with the rule because the value is independent of the evaluation order, even x = v + v because + is commutative.

The recommendation that simple assignments should be used is intended to be restricted to simple assignments of the form x = v and not "simple assignments" according to the ISO definition. However, the recommendation does not have to be followed in order to be compliant with the rule. You should implement the rule (the value should be independent of the evaluation order) for compliance purposes and you might choose to issue a warning for non-simple assignments or you might choose to ignore them.