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 <quanstro@labs.coraid.com> wrote:
On Wed Nov 27 11:04:46 EST 2013, steve@quintile.net 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);
}