Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!bloom-beacon!gatech!rutgers!bpa!cbmvax!uunet!peregrine!ccicpg!puivax!ian From: ian@puivax.UUCP (Ian Wilson) Newsgroups: comp.lang.c Subject: Address error quietly fixed on 680x0 systems Keywords: 68k, sparc, portability Message-ID: <302@puivax.UUCP> Date: 25 Jan 89 08:00:23 GMT Reply-To: ian@puivax.UUCP (Ian Wilson) Distribution: usa Organization: Philips Ultrasound International, Santa Ana, CA. Lines: 43 A piece of code I inherited recently contained the fragment: *((INT_16 *) charbuf_p) = x; charbuf_p += sizeof(INT_16); where charbuf_p had no alignment restrictions enforced, including no restriction on being an odd address. To my surprise, this turns out to work on 680x0 systems, both Sun3 and a vanilla Mac. Looking at the code generated by cc I see a long move: no smarts in the compiler therefore. So the only mechanism that I can be fixing this is an address error trap that quietly moves unaligned objects byte-by-byte as requested. Simple timing experiments on the Sun3 don't appear to bear this out, however; I saw a 50% increase in runtime with writes to an odd address but would have expected more (the trap mechanisms on the 68k aren't super fast after all). Enlightenment? I readily agree that code fragments like the above are to be avoided; here is my offering in the name of portability: improvements welcomed. (Note: checks on buffer size exceeded omitted for clarity). #define WRITE_ANY(x, type) /* eg. WRITE_ANY(f, float) */ \ { type temp = (type) x; \ char *cp = (char *) &temp; \ size_t n = sizeof(type); \ do { *charbuf_p++ = *cp++; } while( --n ); } -- ian wilson PS. the strange loop construct was the only way we could find to get Greenhills C to use `dbf' -- a year or so back though.