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

static analysis weird sign behavior with mixed C and C++ code

在混合 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;

以下两行都给我一个静态工具 (pc-lint) warning 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
}

我尝试了很多转换,但 none 帮助我摆脱了这个警告,为什么?

        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]

多么痛苦...C!

有什么快速解决方法?


看了评论我也试了没成功

     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]

这让我摆脱了 sign/unsigned 混合问题,但这个 "operator '-' followed by operator '+'" 仍然很奇怪!

在C/C++中,小于int的整数被提升为符号相同且与[=一样大的整数10=] 一旦在操作中使用它们 (+...)。

这是历史原因,有点令人困惑,但我想最初的目的是限制溢出 小整数计算的风险。

index_m + 1中,index_m将被提升为unsigned int,然后符号与1不匹配,即signed int

所以在操作完成后你将不得不cast(取决于警告级别)。

What's the quick fix for this?

最简单的是:

 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]

请注意,这只是一条信息消息;不是警告。不过不管怎样,缺少括号的解决方法是加括号:

index_m = ((GetSize() - 1U) + index_m) % GetSize();

或者,显然将操作顺序更改为 (GetSize() + index_m - 1U),如评论中所见