Circular logic with rule 12.1 - 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: Circular logic with rule 12.1 (/showthread.php?tid=993) |
Circular logic with rule 12.1 - jbrookley - 28-10-2013 Hello, I had a violation for rule 10-5 (the result of a Re: Circular logic with rule 12.1 - jbrookley - 28-10-2013 Just a heads up, I am able to fix it with: [code]BurnCount = (ushort16)(EEPROM_BANK0[1]) + (ushort16)((ushort16)(EEPROM_BANK0[0]) Re: Circular logic with rule 12.1 - Steve Montgomery - 29-10-2013 Rule 12.1 deals mainly with operator precedence. For example, the following are exactly equivalent but the rule advises using the second form because it makes the intent absolutely clear: Code: a + (b * c) However, it also mentions associativity of operators in its rationale and suggests using parentheses to control the order in which operations occur. In my opinion, it isn't helpful for Rule 12.1 to try and deal with associativity because Rule 10.1 does a better job of catching those instances where it matters. However, the 2004 rules are superseded by the 2012 ones so I don't think they will be receiving any further technical updates. The problem with associativity is that in algebra, addition is associative, e.g. Code: a + (b + c) == (a + b) + c For example, suppose: Code: unsigned int a = 1u; Consider the expression (a + b) + c on a machine in which int is 16 bits wide and long is 32 bits wide. The rules of C say that the program must behave as if the addition in (a + b) is performed first and then c is added. So, (a + b) is evaluated in the unsigned int type giving 65536. But 65536 doesn't fit in unsigned int so according to the rules of unsigned types in C it's reduced modulo 65536 giving 0. The value is then widened to 32 bits and added to c giving a result with value 1 and type unsigned long. On the other hand the expression a + (b + c) on is evaluated as if the addition in (b + c) is performed first and then a is added. So, according to the C rules, b is first widened to 32 bits and added to c giving 65536 which happily fits in 32 bits. Then a is widened to 32 bits and added to 65536, giving a result with value 65537 and type unsigned long. So, addition isn't necessarily associative in C. There are a few other points to note:
I believe that your tool is flagging a violation of Rule 12.1 because you have mixed types, i.e.: Code: ushort16 + ushort16 + unsigned int You might find that casting your 1u to ushort16 type fixes the problem. But I'd say that you don't have a real issue here anyway because all your types are no wider than unsigned int so the result can't be affected by the order of operation. If it were a problem then I'd expect Rule 10.1 to be flagged as would be the case if you changed your constant from 1u to 1uL for example. That's all a bit complicated but I hope it helps. Re: Circular logic with rule 12.1 - jbrookley - 29-10-2013 Interesting, you hit it right on the head with the different data types. I changed it to: Bur[code]nCount = (ushort16)(EEPROM_BANK0[1]) + (ushort16)((ushort16)(EEPROM_BANK0[0]) Re: Circular logic with rule 12.1 - misra-c - 12-12-2013 The initial example had the underlying types of "( unsigned short + unsigned short ) + unsigned char". This does not violate rule 10.1 or any other MISRA-C:2004 type checking rule. There is also no violation of rule 12.1. |