MISRA-C 规则 10.5

MISRA-C rule 10.5

我有以下静态分析报告,该代码不符合 MISRA-C 规则 10.5:

Results of ~ and << operations on operands of underlying types unsigned char and unsigned short should immediately be cast to the operand's underlying type

密码是:

unsigned val = ~0U;

据我了解,这个想法是必须达到 unsigned int 的最大值,这也可以通过 <limits.h> 中的 unsigned val = UINT_MAX; 来实现。

但是,我想知道这段代码是否有问题。

对我来说,0U 是无符号整数类型,值为 0,然后应用运算符 ~,得到 unsigned int 类型的结果所有位设置为 1 最后它被复制到 unsigned int.

我会说在运算符 ~ 之前没有发生整数提升,因为我们已经有一个 unsigned int.

此外,该工具在代码的其他地方给出了相同的报告:

uint16_t val2 = (uint16_t)(~0U); /* cast is explicit so what is wrong here ? */

我不确定这段代码是否需要修复两个“有问题”的行。

概念基础类型曾用于较旧的 MISRA,如今已弃用并替换为基本类型类别。基础类型的定义是表达式中的每个操作数如果不进行隐式类型提升将具有的类型。

在表达式~0U中,整数常量0U的类型是unsigned int。它不是小整数类型,因此 ~ 上没有整数提升。底层类型与实际的C语言类型相同,unsigned int.

unsigned val = ...unsigned int 分配给 unsigned int。不会通过赋值或其他此类隐式赋值进行左值转换。基础类型仍然是 unsigned int.

因此,如果您的工具在行 unsigned val = ~0U; 上发出关于没有转换为基础类型的警告,您的工具就坏了。


From what i understand, the idea is to have to maximum value of an unsigned int

很有可能。

However, i would like to know if there is something wrong with this code.

不,您的代码没有任何问题。但是,其他 MISRA 规则要求您将默认的“基本类型”替换为来自 stdint.h 的类型(或 C99 之前的编译器上的等效类型)。因此,如果这是一个 32 位系统,则您的代码的 MISRA 兼容版本为 uint32_t val.

uint16_t val2 = (uint16_t)(~0U);

这是符合 MISRA 标准的代码。赋值表达式的基础类型是 uint16_t。强制转换为 uint16_t 是正确且正确的做法。再一次,你的工具坏了。