[英]static analysis weird sign behavior with mixed C and C++ code
Given the following definitions in a mixed C and C++ program: 鉴于混合C和C ++程序中的以下定义:
//in a C file.
uint8_t GetSize()
{
return (uint8_t)something;
}
//in the header of the C++ file.
public:
MyClass(){};
private:
uint8_t index_m;
Both of the following lines give me a static tool (pc-lint) warning 573 . 以下两行给了我一个静态工具(pc-lint) 警告573 。
void MyClass::IncrementWithRollOver(void)
{
index_m = (index_m + 1) % GetSize(); // warning 573 : signed-unsigned mix with divide
}
void MyClass::DecrementWithRollOver(void)
{
index_m = (GetSize() - 1 + index_m) % GetSize(); // warning 573 : signed-unsigned mix with divide
}
I tried lots of casting but none is helping me getting rid of this warning, why? 我尝试了很多铸造,但没有人帮我摆脱这个警告,为什么?
index_m = (index_m + 1U) % GetSize(); // this one works
index_m = (GetSize() - 1U + index_m) % GetSize();// info 834: operator '-' followed by operator '+' could be confusing without parentheses [MISRA 2004 Rule 12.1, advisory]
index_m = (uint8_t)(index_m + (uint8_t)1) % GetSize(); // warning 573 : signed-unsigned mix with divide, and: info 732: loss of sign (assignment) ('int' to 'uint8_t' (aka 'unsigned char')
index_m = (uint8_t)(GetSize() - (uint8_t)1 + index_m) % GetSize(); // warning 573 : signed-unsigned mix with divide, and: info 834: operator '-' followed by operator '+' could be confusing without parentheses [MISRA 2004 Rule 12.1, advisory]
index_m = (uint8_t)(index_m + (uint16_t)1) % GetSize(); // warning 573 : signed-unsigned mix with divide, and: info 732: loss of sign (assignment) ('int' to 'uint8_t' (aka 'unsigned char')
index_m = (uint8_t)(GetSize() - (uint16_t)1 + index_m) % GetSize(); // warning 573 : signed-unsigned mix with divide, and: info 834: operator '-' followed by operator '+' could be confusing without parentheses [MISRA 2004 Rule 12.1, advisory]
what a pain in the ... C! 什么痛苦... C!
What's the quick fix for this? 这是什么快速解决方案?
After reading the comments I also unsuccessfully tried 阅读评论后,我也试过了
index_m = (uint8_t)(index_m + (uint32_t)1) % GetSize(); // works
index_m = (uint8_t)(GetSize() - (uint32_t)1 + index_m) % GetSize(); // info 834: operator '-' followed by operator '+' could be confusing without parentheses [MISRA 2004 Rule 12.1, advisory]
this get me rid of the sign/unsigned mix problem but this "operator '-' followed by operator '+'" is still weird! 这让我摆脱了符号/无符号混合问题,但这个“运算符” - 后跟运算符'+'仍然很奇怪!
In C/C++, integers that are smaller than an int
are promoted to an integer with same sign and as large as an int
as soon as you use them in an operation ( +
...). 在C / C ++中,小于
int
的整数被提升为具有相同符号的整数,并且只要在操作中使用它们就会提升为int
( +
...)。
This is historical and a bit confusing, but I guess the original intent was to limit the risk of overflow on computations with small integers. 这是历史性的,有点令人困惑,但我想最初的意图是限制小整数计算溢出的风险。
In index_m + 1
, index_m
will be promoted to unsigned int
then the sign mismatch with 1
which is a signed int
. 在
index_m + 1
, index_m
将被提升为unsigned int
然后符号与1
不匹配,这是一个signed int
。
So you will have to cast anyway after the operation is done (depending on warning level). 因此,在操作完成后您将不得不进行投射 (取决于警告级别)。
What's the quick fix for this?
这是什么快速解决方案?
Simplest is: 最简单的是:
index_m = (index_m + 1U) % GetSize(); // this one works
ok for incrementation but the problem is with the decrementation...
好的增量,但问题是减少...
index_m = (GetSize() - 1U + index_m) % GetSize();// info 834: operator '-' followed by operator '+' could be confusing without parentheses [MISRA 2004 Rule 12.1, advisory]
Note that this is only an info message; 请注意,这只是一条信息消息; not a warning.
不是警告 But regardless, the solution to lack of parentheses is to add parentheses:
但无论如何,缺少括号的解决方案是添加括号:
index_m = ((GetSize() - 1U) + index_m) % GetSize();
Or, apparently change order of operations to (GetSize() + index_m - 1U)
, as found out in comments 或者,显然将操作顺序更改为
(GetSize() + index_m - 1U)
,如注释中所示
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.