I'm facing MISRA C 2012 violation that I can't understand. Following is the code:
#define I2C_CCRH_FS ((uint8_t)0x80)
#define I2C_CCRH_DUTY ((uint8_t)0x40)
#define I2C_CCRH_CCR ((uint8_t)0x0F)
typedef struct I2C_struct
{
volatile uint8_t CR1;
volatile uint8_t CR2;
volatile uint8_t CCRL;
volatile uint8_t CCRH;
} I2C_TypeDef;
#define I2C_BaseAddress 0x5210
#define I2C ((I2C_TypeDef *) I2C_BaseAddress)
I2C->CCRH &= ~(uint8_t)((I2C_CCRH_FS | I2C_CCRH_DUTY) | I2C_CCRH_CCR);
In the previous code, PC-Lint complains that:
Unpermitted operand to operator '|' [MISRA 2012 Rule 10.1, required]
Mismatched essential type categories for binary operand [MISRA 2012 Rule 10.4, required]
Rule 10.1 states that there should be no problem ORing unsigned int
s. (PC-Lint passes the first OR operation and complains about the second one!!)
Rule 10.4 states that the operands of the operation shall have the same essential type.
I can't understand why these violations exist although all of the operands are declared as uint8_t
?
I've tried puting parentheses around each two of the ORed constants. I've also tried casting all of them to uint8_t
and to volatile uint8_t
. Non solved the violation.
I checked these two posts (1, 2) but they don't answer my question.
(I2C_CCRH_FS | I2C_CCRH_DUTY) | I2C_CCRH_CCR
? Would there be something wrong with the unparenthesizedI2C_CCRH_FS | I2C_CCRH_DUTY | I2C_CCRH_CCR
? – Patrizia#define I2C_CCRH_FS 0x80
and the like? (Or#define I2C_CCRH_FS 0x80u
if it's important to emphasize that they're unsigned?) That way you won't need any casts in the expression, either. MISRA will be happy, and people who (rightly) frown on explicit casts will be happy, too. – Patriziauint8_t
will make the code harder to read and more error prone. So I decided just to disable the error message for this specific line. Do you have a better solution? – Techniqueu
suffix makes MISRA happy and the code safe. – Gawky