From mboxrd@z Thu Jan 1 00:00:00 1970 From: erik quanstrom Date: Wed, 27 Nov 2013 11:31:26 -0500 To: 9fans@9fans.net Message-ID: <12706eb9d1aafea3af76c427a31aae1a@coraid.com> In-Reply-To: <1ebc06ba0079a91546444a93ab21bc65@quintile.net> References: <1ebc06ba0079a91546444a93ab21bc65@quintile.net> MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit Subject: Re: [9fans] compiler bug? Topicbox-Message-UUID: 8c458b9e-ead8-11e9-9d60-3106f5b1d025 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 #include 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); }