MISRA:“基本无符号”类型(无符号字符)的复合表达式在赋值时被转换为更宽的无符号类型,“无符号短”

Joh*_*Doe 0 c misra

剪下我的代码:

uint16 myArray_A[5];
uint8 myArray_B[10] = {0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0x10};
uint8 idx = 0;

for (idx= 0; idx< 5; idx++)
{ 
     myArray_A[idx] = ((myArray_B[idx *2]<<8) | myArray_B[((idx++ *2)+1)]);
}
Run Code Online (Sandbox Code Playgroud)

该代码到目前为止有效。但是我从这个主题中得到了 MISRA 警告。知道如何避免它们吗?

Lun*_*din 8

你在这段代码中有很多问题。

  • 具体的警告很可能是有关的操作数|uint8,但你将它们分配给更广泛的无符号类型uint16。一般来说,如果您要尝试遵守 MISRA ,则需要研究隐式类型的促销规则。MISRA 文件本身也是很好的学习资料。
  • myArray_B[idx *2]<<8与 MISRA 危险代码无关,因为对签名类型进行了静默提升。我建议在使用位移位之前始终转换为大的无符号整数类型。
  • 类似地,对|有符号的提升操作数执行。
  • myArray_A[idx] = ... idx++是常见问题初学者错误,调用未定义的行为。你不能用 C 编写那样的代码。为什么这些构造使用前和后自增未定义行为?.
  • 从 for 循环内部修改循环迭代器是一种可怕的做法,并且违反了 MISRA-C 14.2。
  • 不要使用自制的整数类型,使用stdint.h.
  • MISRA 要求u整数常量的后缀是无符号的(尽管在这种特定情况下无关紧要)。

要修复错误并获得 MISRA-C 合规性,您应该将其重写为以下内容:

uint16_t myArray_A[5];
uint8_t myArray_B[10] = {0x1u,0x2u,0x3u,0x4u,0x5u,0x6u,0x7u,0x8u,0x9u,0x10u};

for (uint8_t i=0u; i<5u; i++)
{ 
     myArray_A[i] = ((uint16_t)myArray_B[i*2u] << 8u) |
                    ((uint16_t)myArray_B[i*2u + 1u]);
}
Run Code Online (Sandbox Code Playgroud)