如何在 C 中正确地将负值转换为无符号类型?

use*_*042 2 c unsigned type-conversion misra

我想存储一个寄存器值并执行bitwise NOT operator如下操作

typedef union TEST_REG {
  uint32_t                         u32Register;
  uint8_t                          Byte[4];
  uint16_t                         hword[2];
} tst_reg;

#define TEST_REGISTER              ((volatile tst_reg*) 0x7023100CUL) // Register
Run Code Online (Sandbox Code Playgroud)

下面是存储值的示例代码

#define CHECK_FLAG                  (0x00000004)
TEST_REGISTER->u32Register &= (uint32_t)(~(CHECK_FLAG));
Run Code Online (Sandbox Code Playgroud)

但是当我执行TEST_REGISTER->u32Register &= (uint32_t)(~(CHECK_FLAG));代码时,QAC会抛出类似的警告

Constant: Negative value cast to an unsigned type
Run Code Online (Sandbox Code Playgroud)

我知道如果我们这样做,NOT (~) operator十六进制值将更改为负数。

所以我想知道如何正确地将负值转换为无符号类型?有什么建议 ?

Joh*_*ger 5

但是当我执行TEST_REGISTER->u32Register &= (uint32)(~(CHECK_FLAG));代码时,QAC 会发出警告,例如

Constant: Negative value cast to an unsigned type
Run Code Online (Sandbox Code Playgroud)

首先,C 并不反对将负整数值转换为无符号类型。该行为是明确定义的。反对的是MISRA。事实上,MISRA 从根本上反对将 应用于~有符号整数类型的表达式,并且它反对将有符号整数类型的复合表达式转换为不同的“基本类型类别”,例如无符号整数。我不确定 QAC 的确切来源,但 MISRA 并不关心正在转换的表达式的值是否实际上为负数。

要做的事情是首先从无符号整数开始。您可以通过在常量后加上uor U:来做到这一点0x00000004u。或者,stdint.h包含用于写入显式宽度类型常量的宏,并通过使用其中适当的宏,您可以解决符号问题并避免强制转换:

#define CHECK_FLAG                  (UINT32_C(0x00000004))
TEST_REGISTER->u32Register &= ~CHECK_FLAG;
Run Code Online (Sandbox Code Playgroud)