我有以下静态分析报告,说明该代码不符合MISRA-C规则10.5:
~和<<<;对基础类型(无符号char和无符号short)操作数的操作应立即强制转换为操作数的基础类型
代码是:
unsigned val = ~0U;
据我所知,其思想是必须具有unsigned int
的最大值,这也可以通过
中的unsigned val=uint_max;
来实现。
但是,我想知道这个代码是不是有问题?
对我来说,0u
是无符号整数类型,且值为0
,然后应用运算符~
,结果为unsigned int
类型,所有位设置为1
,最后将其复制到unsigned int
。
我要说的是,这里在运算符~
之前不会发生整数提升,因为我们已经有了一个无符号int
。
而且,该工具在代码的其他地方给出了相同的报告:
uint16_t val2 = (uint16_t)(~0U); /* cast is explicit so what is wrong here ? */
我不确定这段代码是否需要对这两行“有问题”的代码进行修复。
底层类型的概念在较早的MISRAs中使用,如今已被弃用,并被基本类型类别所取代。基础类型的定义是表达式中每个操作数在不进行隐式类型提升时将具有的类型。
在表达式~0u
中,整数常量0u
的类型是unsigned int
。它不是一个小整数类型,因此在~
上不会进行整数提升。底层类型与实际的C语言类型是相同的,unsigned int
。
无符号val=。。。
将无符号int
分配给无符号int
。不通过赋值或其他此类隐式赋值进行左值转换。基础类型保持unsigned int
。
因此,如果您的工具在unsigned val=~0u;
行上给出一个关于没有强制转换到底层类型的警告,那么您的工具就是坏了。
据我所知,其思想是要使一个无符号int的最大值
很有可能。
但是,我想知道这个代码是不是有问题?
不,你的代码没有问题。但是,其他MISRA规则要求您用stdint.h
中的类型(或C99以前的编译器中的等效类型)替换默认的“基元类型”。因此,如果这是一个32位系统,您的代码的MISRA兼容版本是uint32_t val
。
uint16_t val2=(uint16_t)(~0U);
这是符合MISRA的代码。赋值表达式的基础类型是UINT16_T
。转换到UInt16_T
是正确和适当的做法。你的工具又坏了。