7

我有以下内容:

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},
};
4

3 回答 3

5

(嗨,这是一个新帐户,所以我还不能使用评论部分要求进一步澄清,所以请原谅冗长的回复)

具体来说,本规则 10.3 与 MISRA-C:2012(最新标准)有关,这比之前的版本有了很大的改进,因为在解释 MISRA 的基本原理方面付出了更多努力,并提供了更多合规和不合规的示例。

该规则的基本原理是:由于 C 允许自动执行不同算术类型之间的赋值,因此使用这些隐式转换可能会导致意外结果,并可能丢失值、符号或精度。MISRA_C:2012 有一个基本类型模型来帮助在可能发生这种情况时发出警告。

规则描述还包括规则的例外情况。对于规则 10.3,一个例外是: 本质上有符号类型的非负整数常量表达式可以分配给本质上无符号类型的对象,如果它的值可以用该类型表示。

目前尚不清楚您的工具报告违规行为的确切行和列(它应该)。更好的工具还将提供有关违反规则的确切部分的更详细信息(例如,如果您在第一次分配给 8 位时有 128 而不是 1,则该工具应该非常明确地说明这一点)。

无论如何,我(我的工具也没有)在这里看到任何违反 10.3 的行为。

由于这是一个“可判定的”规则,如果这是对安全至关重要的代码,我会担心该工具,除了它会浪费你的时间。

大多数工具允许您抑制警告并记录原因(在这种情况下,它是工具中的错误)。

如果您的工具供应商需要更多信息,您可以在http://www.misra-c.com的讨论论坛中发布您的问题,以获得官方答案并将其转发给供应商。

于 2015-07-31T21:21:11.783 回答
1

嗯,该规则将使设置 8 位寄存器实际上是不可能的,因为算术运算执行为int或更大(通常的算术转换)。拒绝 MISRA 作为编码标准的另一个理由。

我假设您必须将初始化程序中的每个值都转换为相应字段的类型。但是正如引用的规则,这仍然是违规行为。

于 2015-07-30T14:49:35.693 回答
0

当我使用 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},
};
于 2015-08-06T12:35:22.640 回答