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 [email protected] https://lists.openwrt.org/mailman/listinfo/openwrt-devel
