MISRA Discussion Forums
12.4, reading volatile side effect - Printable Version

+- MISRA Discussion Forums (https://forum.misra.org.uk)
+-- Forum: MISRA C (https://forum.misra.org.uk/forumdisplay.php?fid=4)
+--- Forum: MISRA-C: 2004 rules (https://forum.misra.org.uk/forumdisplay.php?fid=17)
+---- Forum: 6.12 Expressions (https://forum.misra.org.uk/forumdisplay.php?fid=39)
+---- Thread: 12.4, reading volatile side effect (/showthread.php?tid=783)



12.4, reading volatile side effect - jdp - 13-10-2010

Hi,

It's the first Misra compliant project I'm involved in and I've some troubles to understand some rules. On in particular is rule 12.4. I've some expression like

Code:
if (xxx && REGISTER)
where REGISTER is a deference to a volatile pointer (represents the content of a microcontroller register) declared as following:

Code:
#define REGISTER            (*((uword volatile *) 0xEA2CU))

The right and of && doesn't comply to rule 12.4 because of the volatile access. I don't understand why reading a volatile content is not Misra compliant. The problem is that registers access are defined as volatile and I don't know how to overcome this to make my statement compliant.

Thanks for your help.


Re: 12.4, reading volatile side effect - Lundin - 13-10-2010

The MISRA compliant way would be:

Code:
uword reg;
reg = REGISTER;
if(xxx && (reg > 0)) /* no side effect here */

Most of the time, reading volatiles is harmless. You have to evaluate each volatile access from case to case and determine if reading it would be harmful.

Note that all operands of a conditional statement must be of boolean type, according to other MISRA rules. You cannot write if(REGISTER) etc to check against zero, it has to be if(REGISTER > 0).


Re: 12.4, reading volatile side effect - Lundin - 14-10-2010

Lundin Wrote:Note that all operands of a conditional statement must be of boolean type

Oops this isn't correct. Scratch "all operands..." and change that to "the expression...".


Re: 12.4, reading volatile side effect - misra-c - 03-11-2010

Rule 12.4 does not permit side-effects in the right hand operand of a logical operator or in the 2nd and 3rd operands of a conditional operator. The reason for this restriction is that the side-effect may or may not occur.

The method suggested by the previous poster is compliant with Rule 12.4 because the side-effect always occurs.


Re: 12.4, reading volatile side effect - m4l490n - 06-08-2015

misra-c Wrote:The reason for this restriction is that the side-effect may or may not occur.

The method suggested by the previous poster is compliant with Rule 12.4 because the side-effect always occurs.


Could you please explain why does the side-effect may or may not occur? and Why the expression if(xxx && (reg > 0)) forces the side-effect to always occur?

Regards.


Re: 12.4, reading volatile side effect - misra-c - 09-10-2015

The && operator does not evaluate its right-hand operand if the left-hand operand evaluates to False. Therefore any side-effect in the right-hand expression will not occur if the left-hand expression evaluates to False.

Re-writing the code ensures that the volatile is always read.
Code:
#define REGISTER            (*((uword volatile *) 0xEA2CU))
uword reg;
reg = REGISTER;             /* volatile read will always happen */
if(xxx && (reg > 0))
whereas this is not the case in the original code
Code:
#define REGISTER            (*((uword volatile *) 0xEA2CU))
if (xxx && REGISTER)        /* volatile read will only occur if xxx evaluates to True */



Re: 12.4, reading volatile side effect - dgkeb - 03-12-2020

I still don't understand this:
How can I influence the evaluation of the left-hand expression by re-writing the right-hand one?
And also: after re-writing the code the behavior of the && operator should stay the same, means if the left-hand expression is false, the right-hand is not evaluated, is it?

Furthermore I don't understand the reason for this rule: If the first expression is false, the whole expression will be also false anyway. What is the problem? It will be only a problem if the REGISTER must be read every time, e.g. to clear a flag or something.
But I wouldn't put things which have to be done every time in an if-statement.

I have a rule issue with the following loop which waits in a background routine for the end of a transmission. If this doesn't come there is still a timer with which the loop is left after a certain time (to prevent an endless loop). Both are volatile variables and are changed in higher-priority interrupts.

Code:
do {
      } while ((TxFinished == 0) &&          //quit waiting loop when transmission is finished
               (TimeoutTimer != 0));            //or max. waiting time is up

How can I solve this rule?

Thank you and best regards.