简体   繁体   English

静态分析混合C和C ++代码的奇怪符号行为

[英]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 + 1index_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM