我有一段假/示例代码:
#include <stdint.h>
uint8_t func(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 <<= (uint8_t)(val2 & 0x3);
return r;
}
Run Code Online (Sandbox Code Playgroud)
以下是我得到的错误:
$ gcc -Wall -Wextra -Wconversion -O0 module.c -c -o module.o
module.c: In function 'func':
module.c:6:10: warning: conversion from 'int' to 'uint16_t' {aka 'short unsigned int'} may change value [-Wconversion]
6 | val0 += 0x7F;
| ^~~~
module.c:7:10: warning: conversion from 'int' to 'uint16_t' {aka 'short unsigned int'} may change value [-Wconversion]
7 | val1 += (uint16_t)0x7F;
| ^
module.c:8:10: warning: conversion from 'unsigned int' to 'uint16_t' {aka 'short unsigned int'} may change value [-Wconversion]
8 | val2 += 0x7FU;
| ^~~~~
module.c:10:8: warning: conversion from 'int' to 'uint8_t' {aka 'unsigned char'} may change value [-Wconversion]
10 | r <<= (uint8_t)(val2 & 0x3);
| ^
Run Code Online (Sandbox Code Playgroud)
该示例显示了我尝试解决问题的一些方法(例如强制转换)
有什么建议吗?
编辑:
修改示例
这个问题说明了为什么-Wconversion如此过分热情以至于它在很大程度上毫无用处。
在 C 中,没有小于 的算术int。例如:
val0 += 0x7F;
Run Code Online (Sandbox Code Playgroud)
被评估为好像
val0 = (int)val0 + 0x7F;
Run Code Online (Sandbox Code Playgroud)
返回到val0没有强制转换的分配然后触发-Wconversion。从某种意义上说,这是一个合理的警告:+运算符不会溢出,但将结果分配回来可能会丢失部分结果,编译器会告诉您这一点(尽管很笨拙)。
如果要使用-Wconversion,则基本上不能使用+=具有小于int类型的复合赋值运算符(如)。您需要写出等效形式并使用强制转换来表明您打算进行有损转换。例如在这里你会写:
val0 = (uint16_t)(val0 + 0x7F);
Run Code Online (Sandbox Code Playgroud)
我不认为这是非常好的风格,但是一些编码标准/政策(我认为是 MISRA)强制要求它。
| 归档时间: |
|
| 查看次数: |
179 次 |
| 最近记录: |