struct packing reliability?
Matthew Bloch
mattbee@soup-kitchen.net
Tue Feb 26 18:38:00 GMT 2002
Hello all;
I'm trying to make a consistent C interface to various sets of hardware
registers on the Gameboy Advance by using packed structs: for instance, there
is an area of memory which stores an array of 128 64-bit 'objects' which look
like this:
#define PACKED __attribute__((packed))
...
struct _gba_ObjEntry
{
/****** attribute 0 */
/* Y position of Obj */
unsigned int y : 8;
/* Whether to apply rotation and scaling */
unsigned int rotateAndScale : 1;
/* */
unsigned int sizeDouble : 1;
/* */
unsigned int alphaMode : 2;
/* */
unsigned int mosaic : 1;
/* Indicates that a Obj is 256 colour, not 16 */
unsigned int is256colour : 1;
/* Lower two bits of Obj size constant */
enum { Square, Tall, Wide } PACKED shape : 2;
/****** attribute 1 */
/* X position of Obj */
unsigned int x : 9;
union
{
unsigned int rotationIndex : 5;
struct
{
unsigned int unused : 3;
unsigned int x : 1;
unsigned int y : 1;
} PACKED
flipFlags;
} PACKED
transform;
/* Upper two bits of Obj size constant */
enum { Size8, Size16, Size32, Size64 } PACKED size : 2;
/****** attribute 2 */
/* The index of the tile in */
unsigned int firstCharacterIndex : 10;
/* Higher priority Objs are plotted over lower priority Objs */
unsigned int priority : 2;
/* Which palette to use, only relevant for 16 colour Objs */
unsigned int paletteNumber : 4;
/****** attribute 3 */
unsigned int rotationInformation : 16;
} PACKED;
Now as far as I can tell these add up to 64 bits, so I was hoping that I
could define an array at the correct memory address and have this Just Work.
Unfortunately, sizeof(_gba_ObjEntry) == 10, not 8 as I'd expected. My GCC
version gives these diagnostics:
mattbee> arm-agb-elf-gcc -v
Reading specs from
/usr/local/devkitadv/bin/../lib/gcc-lib/arm-agb-elf/3.0.1/specs
Configured with: ../gcc-3.0.1/configure --prefix=/devkitadv
--target=arm-agb-elf --with-cpu=arm7tdmi --without-local-prefix --with-newlib
--with-headers=../newlib-1.9.0/newlib/libc/include/ --with-gc=simple
--enable-multilib --enable-interwork --enable-languages=c++
--enable-targets=arm-elf,arm-coff,arm-aout --disable-win32-registry
--disable-threads -v
Thread model: single
gcc version 3.0.1 (DevKit-Advance)
I have a feeling my structs and unions inside structs complicate matters, but
I can't be sure. My question is: is there any way of getting gcc to pack the
above struct to exactly 64 bits, or should I give up and use hardware
definitions as a set of ugly #defines ? I'd really rather do it this way if
I can, since I'm able to use some handy C semantics rather than needing to do
lots of tedious bit clearing and shifting to get the right results. Even if
gcc *can* be forced to do this, is this a bad route to go down on account of
this behaviour being unenforceable? I'd be reasonably happy if only gcc
could do it but from the documentation I'm beginning to have my doubts.
cheers,
--
Matthew > http://www.soup-kitchen.net/
> ICQ 19482073
More information about the Gcc-help
mailing list