ARM平台意外符号扩展问题:返回值表现与预期不符求解
ARM平台符号扩展问题解答
这是C语言的标准特性,不是BUG,你的预期确实存在错误。
原因分析
- 在C语言的表达式运算规则中,所有小于
int(ARM平台通常为32位)的整型类型(比如int8)会被自动执行整数提升,转换为int类型参与运算。 - 由于
int8是有符号类型,提升时会进行符号扩展:如果值的最高位是1(即负数),会将32位寄存器的高位全部填充为1。比如int8的-1(二进制11111111)会被扩展为32位int的-1(二进制11111111 11111111 11111111 11111111,即0xFFFFFFFF)。 - 当你执行
enc_rot(f->rot) << 14时,被符号扩展后的32位负数移位后,高位的1会保留,最终破坏你预期的位组合结果。
解决方案
- 方案一:在移位前强制转换为无符号8位类型,截断符号扩展的高位:
ais_buf.w[1] = __REV((w0 << 26) | (f->nav_stat << 22) | ((uint8_t)enc_rot(f->rot) << 14) | (sog << 4) | (f->pos_acc << 3) | (w1 >> 25)); - 方案二:如果你的业务逻辑中
enc_rot的返回值不需要作为有符号数使用,直接修改函数返回类型为uint8_t,从根源避免符号扩展问题:uint8_t enc_rot(int16 rot);
内容的提问来源于stack exchange,提问作者M. Sprang
相关产品推荐
相关产品推荐

