Xref: utzoo comp.arch:13301 comp.lang.c:25244 Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!usc!snorkelwacker!spdcc!esegue!johnl From: johnl@esegue.segue.boston.ma.us (John R. Levine) Newsgroups: comp.arch,comp.lang.c Subject: Re: RISC Machine Data Structure Word Alignment Problems? Keywords: risc sun Message-ID: <1990Jan21.224826.1699@esegue.segue.boston.ma.us> Date: 21 Jan 90 22:48:26 GMT References: <111@melpar.UUCP> Reply-To: johnl@esegue.segue.boston.ma.us (John R. Levine) Organization: Segue Software, Cambridge MA Lines: 61 In article <111@melpar.UUCP> toppin@melpar.UUCP (Doug Toppin X2075) writes: >We are using the SUN 4/260 which is a RISC architecture machine. >We are having trouble with data alignment in our data structures. >We have to communicate with external devices that require data structures >such as the following: > struct > { > long a; > short b; > long c; > }; I guess all the world's not a Vax any more, now it's a 68020. It would be more correct to say that your external device requires a four-byte integer, a two-byte integer, and a four-byte integer, all sent highest byte first. C makes no promise that the layout of structures will be the same from machine to machine. For instance, if you ran this code on a 386, there doesn't need to be any padding (though many compilers add it to make the code run faster) but the words are all in the opposite byte order. The SPARC and every other RISC chip requires that items be aligned on their natural boundaries, because there is considerable performance to be gained by doing so, and because it is not very hard to write programs that are totally insensitive to padding and byte order. Many people have observed this. In an article on the IBM 370 series in the CACM about 10 years ago one of the 370's architects noted that the 370 permits misaligned data while its predecessor the 360 didn't, and it was a mistake to have done so because it's rarely used and adds considerable complicated to every 370 machine. In the particular case of the SPARC, there is a C compiler option (documented in the FM) to allow misaligned data at the enormous cost of several instructions and sometimes a subroutine call for every load and store. I presume you are passing byte streams back and forth to your device, a memory mapped interface that requires misaligned operands is too awful to contemplate. You need to write something like this: read_foo_structure(struct foo *p) { p->a = read_long(); p->b = read_short(); p->c = read_long(); } long read_long(void) { long v; /* read in big endian order */ v = getc(f) << 24; /* should do some error checking */ v |= getc(f) << 16; v |= getc(f) << 8; v |= getc(f); return v; } This may seem like more work, but in my experience you write a few of these things and use them all over the place. Then your code is really portable. -- John R. Levine, Segue Software, POB 349, Cambridge MA 02238, +1 617 864 9650 johnl@esegue.segue.boston.ma.us, {ima|lotus|spdcc}!esegue!johnl "Now, we are all jelly doughnuts."