why is mips different (erik's version)?

supermic% ./8.out
78780000
mikro% ./v.out
7878
rpi% ./5.out
78780000



On Wed, Nov 27, 2013 at 8:31 AM, erik quanstrom <[email protected]>wrote:

> On Wed Nov 27 11:04:46 EST 2013, [email protected] wrote:
>
> > Whilst porting some code from the net I came across
> > the attached, rather obscure, code.
> >
> > run as:
> >
> >       larch% 8c -D 'STATIC=static' t.c && 8l t.8 && 8.out
> >       78780000
> >       larch% 8c -D 'STATIC=' t.c && 8l t.8 && 8.out
> >       0
> >
> > I think it is tickling a bug in 8c, though
> > I may be just showing my lack of knowledge of
> > the C standard...
> >
> > anyone any thoughts?
>
> this code is not correct.  it breaks the anti-aliasing rules.  the
> compiler is allowed to assume that tmp is not modified.
> recently had trouble with floating point in stdio for the same
> reasons.
>
> to work around this, use a union, or better yet getle(buf, 3)
> (or be as the case may be),
>
> since there's not enough context to sort out if the original is
> supposed to be big or little endian, here's a union version:
>
> - erik
> ------
> #include <u.h>
> #include <libc.h>
>
> static uint
> getdword_n(void *vmem, int n)
> {
>         uchar *mem;
>         union {
>                 uint    i;
>                 uchar   u[sizeof(uint)];
>         } tmp;
>
>         mem = vmem;
>         tmp.i = 0;
>         switch (n){
>         case 3:
>                 tmp.u[1] = mem[2];
>         case 2:
>                 tmp.u[2] = mem[1];
>         case 1:
>                 tmp.u[3] = mem[0];
>         }
>         return tmp.i;
> }
>
> void
> main(void)
> {
>         uint x;
>
>         char buf[] = "xxxx";
>
>         x = getdword_n(buf, 2);
>         print("%x\n", x);
> }
>
>

Reply via email to