我有简单的代码。在x86(Visual Studio)上,最后两行代码的分辨率相同。
short res;
double CONST = 32768.0
double d=-0.85;
res = ( unsigned short)( d * CONST );
res = ( short)( d * CONST );
在ARM(GCC)上转换为未签名会得到错误的结果。
short dres;
double CONST = 32768.0
double d=-0.85;
dres = ( unsigned short )( d * CONST );
//007db5c4: vldr d17, [pc, #76]
//007db5c8: vldr d16, [r11, #-20]
//007db5cc: vmul.f64 d7, d17, d16 ;d7=={u8 = {51, 51, 51, 51, 51, 51, 219, 192}, u16 = {13107, 13107, 13107, 49371}, u32 = {858993459, 3235590963}, u64 = 13896757370177139507, f32 = {4.17232506e-08, -6.8499999}, f64 = -27852.799999999999}
//007db5d0: vcvt.u32.f64 s15, d7 ;s15==0 !!!!!!!!!!!!!!!!!!!!! incorrect
//007db5d4: vstr s15, [r11, #-48]
//007db5d8: ldrh r3, [r11, #-48]
//007db5dc: uxth r3, r3
//007db5e0: strh r3, [r11, #-6]
dres = ( short )( d * CONST );
//007db5e4: vldr d17, [pc, #44]
//007db5e8: vldr d16, [r11, #-20]
//007db5ec: vmul.f64 d16, d17, d16
//007db5f0: vcvt.s32.f64 s15, d16 ;s15==-nan(0x7f9334)
//007db5f4: vmov r3, s15
//007db5f8: strh r3, [r11, #-6]
这是正确的行为还是错误?
答案 0 :(得分:2)
这不是编译器错误。
对于16位short
,其行为
res = ( unsigned short)( d * CONST );
由于您溢出signed
类型的和将float
的值转换为-1
的情况下,未定义 小于unsigned
整数类型。这会将整个程序置于未定义状态。