我有以下内容:
typedef struct
{
uint8_t BlockID;
uint32_t Copies;
uint16_t Size;
}NVMM_ConfigType;
const NVMM_ConfigType NvmmCnf_Layout[6] =
{
{ 1, 1, 4},
{ 2, 3, 4},
{ 5, 5, 16},
{ 10, 1, 4},
{ 11, 2, 32},
{ 13, 1, 100},
};
这对我来说似乎很好,但是,MISRA-C给出以下错误:
MISRA C:2012规则10.3违规:[R]表达式的值不应赋给具有较窄基本类型或不同基本类型类别的对象
我试图弄清楚为什么会发生这种情况,但我就是看不出来。在类似的情况下,构建结果也会受到这个错误的困扰,我不知道为什么。
有人知道发生了什么事吗?
编辑:我也试图显式转换每个值,仍然得到相同的错误:
const NVMM_ConfigType NvmmCnf_Layout[6] =
{
{ (uint8_t)1, (uint32_t)1, (uint16_t)4},
{ (uint8_t)2, (uint32_t)3, (uint16_t)4},
{ (uint8_t)5, (uint32_t)5, (uint16_t)16},
{ (uint8_t)10, (uint32_t)1, (uint16_t)4},
{ (uint8_t)11, (uint32_t)2, (uint16_t)32},
{ (uint8_t)13, (uint32_t)1, (uint16_t)100},
};
(嗨,这是一个新帐户,所以我还不能使用评论部分要求进一步澄清,所以请原谅我的长回复)
具体来说,此规则10.3适用于MISRA- c:2012(最新标准),这是对先前版本的巨大改进,因为在解释MISRA的基本原理方面做了更多的努力,以及更多符合和不符合的示例。
该规则的基本原理是:由于C允许自动执行不同算术类型之间的赋值,因此使用这些隐式转换可能导致意想不到的结果,可能会丢失值、符号或精度。MISRA_C:2012有一个基本的类型模型来帮助在可能发生这种情况时发出警告。
规则描述还包括规则的例外。对于规则10.3,一个例外是:本质上有符号类型的非负整数常量表达式可以赋值给本质上无符号类型的对象,如果它的值可以用该类型表示。
不清楚你的工具报告违规的确切行和列(它应该)。更好的工具还将提供更详细的信息,确切地说明规则的哪一部分被违反了(例如,如果你在第一次赋值到8位时不是1,而是128,工具应该非常明确地说明这一点)。
无论如何,我(我的工具也没有)看到这里有任何违反10.3的地方。
由于这是一个"可决定的"规则,除了它在浪费您的时间之外,如果这是安全关键代码,我会关心这个工具。
大多数工具允许您取消警告并记录原因(在这种情况下是工具中的错误)。
如果您的工具供应商需要进一步的信息,您可以在讨论论坛http://www.misra-c.com上发布您的问题,以获得官方答案,并将其转发给供应商。
嗯,该规则将使设置8位寄存器实际上是不可能的,因为算术运算被执行为int
或更大(通常的算术转换)。另一个拒绝MISRA作为编码标准的理由。
我假设您必须将初始化器中的每个值强制转换为各自字段的类型。但正如引用的规则,这仍然是违反的。
当我使用PC-Lint检查Misra规则时,我经常发现自己需要在常量中添加u
后缀:
const NVMM_ConfigType NvmmCnf_Layout[6] =
{
{ 1u, 1u, 4u},
{ 2u, 3u, 4u},
{ 5u, 5u, 16u},
{ 10u, 1u, 4u},
{ 11u, 2u, 32u},
{ 13u, 1u, 100u},
};
这消除了int
到unsigned
的转换。
如果这还不够,那么强制转换:
const NVMM_ConfigType NvmmCnf_Layout[6] =
{
{ (uint8_t ) 1u, 1u, (uint16_t ) 4u},
{ (uint8_t ) 2u, 3u, (uint16_t ) 4u},
{ (uint8_t ) 5u, 5u, (uint16_t ) 16u},
{ (uint8_t )10u, 1u, (uint16_t ) 4u},
{ (uint8_t )11u, 2u, (uint16_t ) 32u},
{ (uint8_t )13u, 1u, (uint16_t )100u},
};