如何修复由-Wconversion引起的错误?
我有一段假代码/示例代码:如何修复由-Wconversion引起的错误?,c,gcc,C,Gcc,我有一段假代码/示例代码: #包括 uint8_t函数(uint16_t val0、uint16_t val1、uint16_t val2) { uint8_t r; val0+=0x7F; val1+=(uint16_t)0x7F; val2+=0x7FU; r=(uint8_t)((val0+val1+val2)>>8); r这个问题说明了为什么-Wconversion过于热心以至于基本上没有用 在C语言中,没有小于int的算术运算。例如: val0 += 0x7F; 被评估为 val0
#包括
uint8_t函数(uint16_t val0、uint16_t val1、uint16_t val2)
{
uint8_t r;
val0+=0x7F;
val1+=(uint16_t)0x7F;
val2+=0x7FU;
r=(uint8_t)((val0+val1+val2)>>8);
r这个问题说明了为什么-Wconversion
过于热心以至于基本上没有用
在C语言中,没有小于int
的算术运算。例如:
val0 += 0x7F;
被评估为
val0 = (int)val0 + 0x7F;
不使用强制转换将赋值返回到val0
,然后触发-Wconversion
。从某种意义上说,这是一个合理的警告:+
运算符不会溢出,但将结果返回可能会丢失部分结果,编译器会告诉您这一点(尽管有些尴尬)
如果要使用-Wconversion
,基本上不能将复合赋值运算符(如+=
)用于小于-int
的类型。您需要写出等价的表单,并使用强制转换来指示要进行有损转换。例如,在这里您可以编写:
val0 = (uint16_t)(val0 + 0x7F);
我不认为这是一种非常好的风格,但一些编码标准/策略(例如,我认为,MISRA)强制要求它。强制转换/位掩码可以做到这一点
例如:
#包括
uint8_t函数(uint16_t val0、uint16_t val1、uint16_t val2)
{
无符号整数r;
val0=(uint16_t)(val0+0x7Fu);
/*val0=(val0+0x7Fu)&0xFFFF*/
val1=(val1+0x7Fu)&0xFFFF;
val2=(val2+0x7FU)&0xFFFF;
r=((0u+val0+val1+val2)>>8);
r=(r升级编译器版本如果可能的话,-Wconversion
的早期版本会产生一些像这样可怕的误报,而且它比以前稍微好一些time@M.M我使用gcc 9.2.1OK,似乎他们还有一些改进的空间+1“尝试并避免短于int的类型可能是个好主意”。即使没有-Wconversion
,这也是正确的。使用此类类型几乎总是一个错误,尤其是对于参数/局部变量。它们主要用于数组或结构中的大容量存储,其中int
或更大的值将消耗更多的空间。
val0 = (int)val0 + 0x7F;
val0 = (uint16_t)(val0 + 0x7F);
#include <stdint.h>
uint8_t func(uint16_t val0, uint16_t val1, uint16_t val2)
{
unsigned int r;
val0 = (uint16_t)(val0 + 0x7Fu);
/*val0 = (val0 + 0x7Fu) & 0xFFFF;*/
val1 = (val1 + 0x7Fu) & 0xFFFF;
val2 = (val2+0x7FU) & 0xFFFF;
r = ((0u+val0+val1+val2) >> 8);
r = ( r << (uint8_t)(val2 & 0x3u)) & 0xFF;
return r&0xFF;
}