C 如何解决有关应用位运算符的Misra警告~和<&书信电报;对于基础类型

C 如何解决有关应用位运算符的Misra警告~和<&书信电报;对于基础类型,c,embedded,misra,C,Embedded,Misra,我有以下声明 CAN0_CTL_R &= ~ CAN_CTL_INIT; 以及所需的misra警告: 如果位运算符~和据我所知,警告不适用于您提供的语句,给定您所说的宏定义apply。然而,我推测它与整数常量0x00000001U有关。解释为整型常量,类型为unsigned int,但MISRA工具可能会错误地将其解释为具有较窄的类型,因为其值适合较窄的类型 我建议通过明确指定类型来减少机器或人类误解的可能性: #define CAN_CTL_INIT ((uns

我有以下声明

CAN0_CTL_R &= ~ CAN_CTL_INIT;
以及所需的misra警告:


如果位运算符~和据我所知,警告不适用于您提供的语句,给定您所说的宏定义apply。然而,我推测它与整数常量
0x00000001U
有关。解释为整型常量,类型为
unsigned int
,但MISRA工具可能会错误地将其解释为具有较窄的类型,因为其值适合较窄的类型

我建议通过明确指定类型来减少机器或人类误解的可能性:

#define CAN_CTL_INIT            ((unsigned int) 0x00000001U)  // Initialization


。前者在每个符合条件的C实现上产生一个与原始表达式类型和值相同的表达式。后者对你来说可能相当,你可能更喜欢它的风格。(如果后者对你来说不是等价的,那么你应该考虑它实际上是你想要的。)你使用了哪个MISRA检查器?至少对于TI编译器来说,这已经被证实是一个假阳性:这是一个有效的问题,恰当地标记了MISRA。您看到的是D.6的结果(附录D,基本类型);在D.6中,CAN_CTL_INIT有一个基本类型的
uint8_t
,因此在MISRA中,~CAN_CTL_INIT可能会产生0xFF。警告指示您应将结果强制转换为此类型(
uint8\t
),以使此结果具有确定性,即消除整数提升的结果。该规则可防止与具有不同整数大小的编译器相关的错误。您在那里的意图很可能是从该补码中得到0xFFFFFE,如果编译器有16位整数,这种情况就不会发生。@Jubatian:
0x1U
的类型是
无符号整数
,而不是
uint8\u t
(即
无符号字符
),而不是
无符号短字符
。请阅读下面的C标准!MISRA工具在这里是正确的,MISRA-C-2012,附录D(基本类型),D.6定义了在此应用的规则。CAN_CTL_INIT的基本类型是
uint8_t
,如果海报预期补码结果为0xFFFFFE,并使用具有16位int size的编译器编译(结果为0xFFFE),那么它将真正产生错误。当然,这种情况不会发生,因为这种特殊情况显然是特定于硬件的,但MISRA规则的目的是防止此类错误。@Jubatian:根据显示的代码,宏
可以计算为(宏没有类型)
0x00000001U
,这是一个
无符号int
uint8\u t
。类型不能为
unsigned int
,也不能为
unsigned short
。所以,不,这里不适用。补码不改变类型,并且为无符号的补码定义良好。我同意位数取决于实现,但是
unsigned int
的位数不能少于16位。
#define CAN_CTL_INIT            ((unsigned int) 0x00000001U)  // Initialization
#define CAN_CTL_INIT            ((uint32_t) 0x00000001U)  // Initialization