c - MISRA 警告 12.4 : integer conversion resulted in truncation (negation operation)

标签 c truncate misra coverity negation

在一个针对 16 位处理器的程序中的巨大宏中,以下代码(简化的)出现了多次:

typedef unsigned short int  uint16_t;
uint16_t var;
var = ~0xFFFF;

MISRA 提示警告 12.4:整数转换导致截断。用于获取此信息的工具是 Coverity。

我已经检查过论坛,但我确实需要一个解决方案(而不是通过实际值更改否定),因为这一行位于具有不同参数的宏内。

我尝试了很多事情,这是最后的尝试,但也失败了:

var = (uint16_t)((~(uint16_t)(0xFFFFu))&(uint16_t)0xFFFFu);

(值0xFFFF只是一个例子。在实际代码中,该值是一个变量,可以取任何值(但16位))

请问您还有其他想法吗?谢谢。

编辑:

然后我尝试使用32位值,结果与以下代码相同:

typedef unsigned int uint32_t; 
uint32_t var; 
var = (uint32_t)(~(uint32_t)(0xFFFF0000u));

最佳答案

摘要:

假设您使用 MISRA-C:2012 静态分析器,您应该会收到违反规则 10.3 和 7.2 的警告。

规则 12.4 仅涉及无符号整型常量的环绕,这种情况只能与二元 + 和 - 运算符一起出现。这里似乎无关紧要。


警告文本对于 MISRA-C:2004 12.4 和 MISRA-C:2012 12.4 似乎都没有意义。该工具可能显示错误的警告。

但是,MISRA:2012 规则 10.3 禁止将值分配给类型小于表达式中预期类型的​​变量。

要使用 MISRA 术语,~0xFFFF基本类型是无符号的,因为十六进制文字的类型为 unsigned int。在您的系统上,unsigned int 显然大于 uint16_t(int 是标准 6.3.1.1 中比短整型“排名更高”的整数类型,即使它们属于尺寸相同)。也就是说,uint16_t 的基本类型比 unsigned int 更窄,因此您的代码不符合规则 10.3。这是您的工具应该报告的内容。

隐藏在 MISRA 术语背后的实际技术问题是 ~ 运算符很危险,因为它带有隐式整数提升。这又会导致像这样的代码

uint8_t x=0xFF; 
~x << n; // BAD, always a bug

当值 0xFFFFFF00 左移时调用未定义的行为。

因此,将 ~ 运算符的结果转换为正确的预期类型始终是一种良好的做法。 MISRA 2004 中甚至对此有明确的规则,现已合并到“基本类型”规则中。

此外,MISRA (7.2) 规定所有整数常量都应具有 uU 后缀。

符合 MISRA-C:2012 的代码如下所示:

uint16_t var;
var = (uint16_t)~0xFFFFu;

或者过于迂腐:

var = (uint16_t)~(uint16_t)0xFFFFu;

关于c - MISRA 警告 12.4 : integer conversion resulted in truncation (negation operation),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40377804/

相关文章:

使用 fork() 时计数器不会在 a 内增加

PHP 截断文本 base64

c - 如何解决有关对基础类型应用按位运算符 ~ 和 << 的 Misra 警告

C代码: for loop compiles with gcc but doesn't run

c - 如何在 C 中使用迭代器宏来防止阴影

Oracle PLSQL 将日期时间截断为特定小时

mysql - 我需要截断一个表然后插入新的寄存器,但用户看不到这个

c - 指针 MISRA 违规的算术

c - 尝试修复不匹配的 MISRA 违规规则 10.4 : unsigned 32-bit int and signed 32-bit int,

C 链表冒泡排序逻辑错误