在C中使用带有位运算符的小整数

no_*_*ame 10 c misra type-promotion

之前的问题相关,我无法理解MISRA C 2004的一些规则.

ISO C99 2007草案中,在6.5节§4中:

一些运算符(一元运算符〜,以及二元运算符<<,>>,&,^和|,统称为按位运算符)需要具有整数类型的操作数.这些运算符产生的值取决于整数的内部表示,并且具有已签名类型的实现定义和未定义方面.

好吧,使用带位运算符的有符号整数可能会产生未定义的行为(并没有任何意义).

一个好的解决方案是使用显式转换为更宽的无符号整数类型,以便绕过整数提升,然后不使用带符号运算符的有符号值(请参阅我之前问题的相关答案).

但是在MISRA C 2004中,可以使用带位运算符的小型无符号整数(例如规则10.5).为什么,如果整数提升导致使用带位运算符的带符号值?我想我不明白一些事情.

Jam*_*oth 1

这些规则并不相互矛盾,您也不需要扩大类型。您可以立即将小整数二进制运算的结果转换回其类型。

除非第一个操作数是 int,否则小整数不会因移位而提升为 int。

这是来自他们的例子:

uint8_t port = 0x5aU;
uint8_t result_8;
uint16_t result_16;

result_8 = (~port) >> 4;  /* not compliant */
result_8 = ((uint8_t)(~port)) >> 4; /* compliant */
result_16 = ((uint16_t)(~(uint16_t)port)) >> 4; /* compliant */
Run Code Online (Sandbox Code Playgroud)

  • -1 这个答案不正确。请参见 C11 6.5.7 `对每个操作数执行整数提升。结果的类型是提升后的左操作数的类型。 (4认同)
  • E1和E2是指整数提升后的操作数。您引用的文本指的是当您将负数的符号位移入和移出时发生的指定不明确的行为。 (2认同)
  • @JérômeBurlando 要点是,如果您将 ~ 应用于现在已签名 int 的提升变量,您将在 ms 字节中得到垃圾。但是,如果您立即将变量强制转换回 uint8_t,您将丢弃垃圾字节。 (2认同)