我们正在使用Parasoft Static Analysis并启用了MISRA C 2004检查程序。
该软件是一个嵌入式系统。我们喜欢按如下方式描述常量:
[1] #define MOTOR_ON (1 << 9)
这表明寄存器中的第9位应为1以打开电机。
表达式是MISRA失败,所以我们改变了它:
[2] #define MOTOR_ON (1U << 9U)
更改转换为无符号整数常量,因为最好使用无符号整数进行移位。
语句2中的表达式仍然失败,因为右手操作符(9U)需要检查。根据MISRA,如果右手操作符大于左手操作符的底层类型的位宽,则存在问题。
问题的根源是1U的基础类型为unsigned char
或8位
我们写的寄存器是16位,所以理论上没有问题。
如何更改[2]中的表达式,使其通过MISRA C 2004,更喜欢不使用强制转换?
我正在使用IAR Embedded Workbench和8/32位模式的ARM7TDMI处理器。
编辑1:示例代码。
void turn_on_motor(void);
#define MOTOR_ON (1U << 9U)
void turn_on_motor(void)
{
uint16_t * const p_motor_control = (uint16_t *)(0x01234567U);
*p_motor_control = MOTOR_ON;
}
错误文本:用作移位运算符右侧操作数的常量应受限制。
来自Parasoft提供的MISRA规则文档:
Rule reports a violation if:
- the right-hand operand is a constant with negative value or with value that
exceeds the length (in bits) of the left-hand operand
- the right-hand operand is not a constant and is not checked by specific
pattern
答案 0 :(得分:3)
我的建议是定义一个隐藏丑陋铸造的宏,然后继续进行丑陋的施法以使MISRA高兴。
类似的东西:
#define LSHIFT(x, n) \
(((unsigned int)(x)) << ((unsigned int)(n)))
然后在您的实际代码中:
#define MOTOR_ON LSHIFT(1, 9)
编辑:在下面的评论中,@ Lundin说MISRA会抱怨类似函数的宏。我从未使用过MISRA所以我不知道。
快速Google搜索会发现MISRA有一些特殊注释可以添加到您的代码中以禁用警告。这表明有两种可能性:
在定义LSHIFT()
和RSHIFT()
以及任何其他位操作宏的头文件中,将宏定义包装在MISRA警告禁用注释中。
在您想要进行位移的源文件中,添加MISRA警告禁用注释,然后将代码放在之前。
http://www.gimpel.com/Discussion.cfm?ThreadMode=Prev&ThreadID=2261
如果我理解正确,MISRA具有全局启用/禁用功能,但没有禁用,然后“按原样放回”。因此,禁用然后启用的注释将始终全局启用检查,因此理想情况下,这些魔术注释不应位于头文件中。
所以我想我现在的建议是将原来的位移代码放在.C源文件中,然后将魔术注释用于禁用/启用位移代码周围的MISRA警告。
答案 1 :(得分:1)
你也可以通过使用
来避免转移问题 #define MOTOR_ON ((uint16_t)512U) /* 1 << 9 = 2^9 */
答案 2 :(得分:0)
表达式的值被分配给具有较窄类型的对象。 “1U&lt;&lt; 9U“仅导致保留低位。
用丑陋的演员“让MISRA高兴”不会改变这个事实,虽然一个糟糕的工具可能会被游戏,但它不应该。直截了当的解决方案是使用显式转换:
#define MOTOR_ON ((uint16_t)0x200) /* 9th bit on turns on motor */
但是如果您认为“转换更易于阅读”,那么只需关闭此案例的规则并记录推理。如果事实上完全符合性是不可能的,那么在符合MISRA的开发中,偏差过程是完全正确的(并且是鼓励的)。您必须让偏差管理流程完全符合要求。意识的证据是目标,而不是一致性的证据。
BTW,@ Thomas,你说得对,这也不是你写的MISRA C:2004, error with bit shifting的完全重复。虽然它违反了规则10.3,但所描述的“基础类型”概念对于理解此警告对此特定问题的意图几乎没有帮助。我向大家提出的建议是看看最新版本的MISRA-C:2012中的规则10.3的描述(见http://misra.org.uk),这使得工程师和工具制造商的概念和意图更加清晰。