On Sat, Apr 27, 2013 at 09:24:41PM +0200, Wojciech Kromer wrote: > > > Note that adding an explicit u32 cast avoids the problem even with a buggy > > compiler: > > > > static inline u32 get_unaligned_le32(const u8 *p) > > { > > return (u32)p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24; > > } > > > Generally it's a good idea to write explicit type conversions like in > this example. > Poor precompiler/optimizer could treat inline just like a macro (which > is wrong) > > Without that (u32) first conversion in this code is probably not > specified so it is defaulted to int. > With a buggy version we probably have: > ( (int)p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24 ) > as a result.
Even worse - every operand is first promoted to int, and if you read the C99 standard literally, the behavior of p[3] << 24 is undefined if p[3] >= 128. But I cannot imagine that compiler developers could dare to break such code deliberately. > Of course conversion should be found as function return type. Yes, and putting an explicit conversion around the whole expression: return (u32)(p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24); does NOT change the generated code at all.
signature.asc
Description: Digital signature
_______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel