CCHD@lure.latrobe.edu.au (Huw Davies - La Trobe University Computer Centre) (02/14/91)
I have a slight problem with the c compiler (on MIPS 120/5 running RISC/os 4.5.1). The following code doesn't do what I want :-) Please note that this is an example of the error extracted from debugging 6K lines of c code (It took a while to find....). $ more test_struct.c #include <stdio.h> struct test { short a; int b; } c; main() { printf("a: %x\nb: %x\nSize of a: %d\n", &c.a, &c.b, (int) &c.b - (int) &c.a); } $ ./test a: 2003e460 b: 2003e464 Size of a: 4 $ I would have liked the difference in address to be 2, not 4. I know that there are efficiency reasons for aligned access, but I would like to be able to override the default. For those few of you who read comp.unix.aix as well (there's got to be someone else who believes in vendor independence...) I have the same problem with our RS/6000 systems. (Different implementation - same bugs :-) Huw Davies Computing Services e-mail: cchd@lucifer.latrobe.edu.au
sah@batman (Steve Hanson) (02/15/91)
In article <5054@lure.latrobe.edu.au>, CCHD@lure (Huw Davies - La Trobe University Computer Centre) writes: >I have a slight problem with the c compiler (on MIPS 120/5 running RISC/os >4.5.1). > >The following code doesn't do what I want :-) Please note that this >is an example of the error extracted from debugging 6K lines of c code >(It took a while to find....). > >$ more test_struct.c >#include <stdio.h> > >struct test >{ > short a; > int b; >} c; > >main() >{ > printf("a: %x\nb: %x\nSize of a: %d\n", &c.a, &c.b, > (int) &c.b - (int) &c.a); >} > >$ ./test >a: 2003e460 >b: 2003e464 >Size of a: 4 >$ > >I would have liked the difference in address to be 2, not 4. I know >that there are efficiency reasons for aligned access, but I would like >to be able to override the default. > >For those few of you who read comp.unix.aix as well (there's got to be >someone else who believes in vendor independence...) I have the >same problem with our RS/6000 systems. (Different implementation - same >bugs :-) > >Huw Davies >Computing Services > >e-mail: cchd@lucifer.latrobe.edu.au Taken from the 2.20, in Beta now, release notes: o #pragma pack(n) #pragma pack() The first form is used to change the strictest alignment of structure members within a structure. n is the new alignment restriction in bytes. If n is omitted, then it defaults to the compiler option -Zp, if present, or the compiler default, which is the strictest member alignment. Your code would look like: #include <stdio.h> #pragma pack(2) struct test { short a; int b; } c; main() { printf("a: %x\nb: %x\nSize of a: %d\n", &c.a, &c.b, (int) &c.b - (int) &c.a); } with the ouput: a: 10000b7c b: 10000b7e Size of a: 2
cprice@mips.COM (Charlie Price) (02/16/91)
In article <5054@lure.latrobe.edu.au> CCHD@lure.latrobe.edu.au (Huw Davies - La Trobe University Computer Centre) writes: >I have a slight problem with the c compiler (on MIPS 120/5 running RISC/os >4.5.1). > >The following code doesn't do what I want :-) Please note that this >is an example of the error extracted from debugging 6K lines of c code >(It took a while to find....). > >$ more test_struct.c >#include <stdio.h> > >struct test >{ > short a; > int b; >} c; > >main() >{ > printf("a: %x\nb: %x\nSize of a: %d\n", &c.a, &c.b, > (int) &c.b - (int) &c.a); >} > >$ ./test >a: 2003e460 >b: 2003e464 >Size of a: 4 >$ > >I would have liked the difference in address to be 2, not 4. I know >that there are efficiency reasons for aligned access, but I would like >to be able to override the default. > >For those few of you who read comp.unix.aix as well (there's got to be >someone else who believes in vendor independence...) I have the >same problem with our RS/6000 systems. (Different implementation - same >bugs :-) You seem to assume that fields in a struct will be packed. That isn't C. The compiler won't pack fields for you, you have to do mis-alignment by hand. When I need to use a packed (or otherwise oddly aligned) external format, I normally read-and-unpack-from-odd-format into a C structure, write the program to reference the C struct elements, and pack-into-odd-format-and-write when I need to get it out. This way, I control the pack and unpack and can possibly even write this in a completely portable way. MIPS has unaligned access library routines that would help you write the unpack and pack parts. The routines are in unaligned(3). If it is important to you, for some reason, to run a program that has unaligned references then MIPS helps you out. In the program that will do this, you have to either: * do the load/store by calling MIPS-supplied library routines that do unaligned references (see unaligned(3)). * call a MIPS-supplied signal-catcher once to emulate unaligned references when they occur (see unaligned(3)). * make a MIPS-specific system call at the program start to have the the kernel emulate unaligned refs when they occur (see sysmips(2)). The MIPS-supplied signal handler package catches the SIGBUS signal caused by the unaligned reference, emulates the unaligned reference, and keeps track of how many it sees of each type. The package has a way to let you print a report that tells you how many references of each type it fixed up. This package is also the one with library routines you can call directly to do unaligned loads and stores. If you don't mind even less portable code, then you can make a MIPS-specific system call that tells the kernel to look for and emulate unaligned references whenever you get a bus error rather than give your process a SIGBUS. The MIPS-specific calls are documented in sysmips(2), and you want to look at MIPS_FIXADE. The fastest performance is to write programs that don't need to make alignment assumptions. The next fastest is to use the library routines to do the unaligned references each place you do one. The emulation choices are VERY VERY slow, relative to a lw instruction. You pay a high price for the convenience of running code that has unaligned references -- but at least we help out. -- Charlie Price cprice@mips.mips.com (408) 720-1700 MIPS Computer Systems / 928 Arques Ave. / Sunnyvale, CA 94086-23650