混合 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)
,如评论中所见
在混合 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)
,如评论中所见