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.

Attachment: signature.asc
Description: Digital signature

_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel

Reply via email to