32位ARM平台Go语言无类型int常量溢出问题求助
解决Go中32位ARM下用十六进制字面量处理C返回有符号整数的问题
核心问题
你在32位ARM系统编译Go代码时,尝试用十六进制字面量0xF3210123匹配C函数返回的32位有符号整数,但该值作为无类型整数常量会溢出32位int的范围(32位int最大值为2147483647,而0xF3210123的十进制是4079026467),导致编译错误。
简便解决方案
方法1:直接将switch表达式转为int32
32位ARM下C.int等价于int32,将输入值转为int32后,case中的十六进制字面量会被自动解析为32位补码的有符号值,无需额外转换:
func ResultToString(value C.int) error { switch int32(value) { case 1: return nil case -1: return fmt.Errorf("Unknown") case 0xF3210123: // 自动解析为int32类型的-215940829 return fmt.Errorf("Line high") } return fmt.Errorf("bad value") }
方法2:预定义带类型的常量
如果需要复用该值,可以先定义int32类型的常量,再在case中使用:
const ErrLineHigh = int32(0xF3210123) func ResultToString(value C.int) error { switch int(value) { case 1: return nil case -1: return fmt.Errorf("Unknown") case int(ErrLineHigh): return fmt.Errorf("Line high") } return fmt.Errorf("bad value") }
方法3:case内直接类型转换
如果不想修改switch的表达式类型,可以在case中通过两次转换得到正确值:
func ResultToString(value C.int) error { switch int(value) { case 1: return nil case -1: return fmt.Errorf("Unknown") case int(int32(0xF3210123)): // 先转int32得到补码值,再转int return fmt.Errorf("Line high") } return fmt.Errorf("bad value") }
原理说明
Go中无类型整数常量默认会尝试匹配int类型,但32位ARM下int是32位,无法容纳0xF3210123的无符号值。而将常量转为int32时,Go会按32位补码规则解析该十六进制值,自动得到对应的有符号负数-215940829,再转成int(32位)也不会溢出。
内容的提问来源于stack exchange,提问作者ajn
相关产品推荐
相关产品推荐

