[comp.lang.c] structure alignment

unhd (Roger Gonzalez ) (03/30/90)

THE APPLICATION: a standalone file system for a WORM drive.

THE TASK: to build a structure to be overlaid on 2048 bytes of memory
that holds the contents of a disk block.

THE PROBLEM: I cannot figure out how to specify some of the structures,
since one of their elements is an array of size (2048 - everything else).
My first cut is shown below, but I believe that it may fail if the structure
ends on an uneven word(?) boundary.  The important structure below is
Header_block.  The others are substructures.

typedef struct {			One important issue that I
    Byte	hunsec;			need to figure out is whether
    Byte	second;			structures are padded to an
    Byte	minute;			even boundary *within* the
    Byte	hour;			structure, or *outside* the
    Byte	dow;			structure.  In other words,
    Byte	date;			would sizeof(Calendar) return
    Byte	month;			9 or 10 (assuming 2 byte word
    U_short	year;			alignment)
} Calendar;

typedef struct {
    char        type;
    char        name[20];
    Byte        version;
    Calendar    cal;			This is the above structure
    U_long      hbn;
    U_long      tbn;
    U_long      dbn;
    U_long      next;
    U_long      prev;
} Block;


typedef struct {				The format block structure and
    Block       block;				the next type, header block,
    char        data[2048 - sizeof(Block)];	must be exactly 2048 bytes
} Format_block;					in length.

typedef struct {				This is where I think things
    Block       block;				will get screwy.  In format
    char        owner[4];			block, I just subtract the
    U_short     fid;				size of the Block structure
    U_short     pfid;				to find out how long to make
    U_short     databytes_in_block;		the data array.  I'm assuming
    Byte        data[2048 - sizeof(Block) - 10];	that the calendar
} Header_block;					structure gets padded inside,

right before "year".  So then cal ends on an even boundary, and the size of
the array is correct.  In header block, however, I'm not certain what will
happen.  The "-10" is to account for the 10 bytes of *defined* fields in
the structure, but what if some alignment takes place?  It could be 11 bytes.

If you're not following me, here's a picture:
___________	Assume that this block *must* be 20 bytes long.  If structure
| 9 bytes |	1 is 9 bytes long, and structure 2 is 8 bytes, and alignment
|_________|			is to even numbers, I cannot just make data
|_________|<- 1 byte padding	be (20 - 9 - 8), because there is an extra
| 8 bytes |			byte in the pudding.
|_________|
|_________|<- data[?]


Now that I've bored you all... HELP!!
Could I define things differently?  What I wanted to do was:

Byte block[2048];

get_block(bn, block);

switch(block[0])
	case HB:
		hb = (Header_block *) block;
		tbn = hb->block.tbn;
		...

etc.

Any help will be greatly appreciated.  I really don't want to go hand tailor
it to my machine/compiler by putting dummy fields into structures, but if I
must, I must.

Thanks,
Roger
-- 
UUCP:   ..!uunet!unhd!rg      | USPS: Marine Systems Engineering Laboratory
BITNET: r_gonzalez at unhh    |       University of New Hampshire
PHONE:  (603) 862-4600        |       Marine Programs Building
FAX:    (603) 862-4399        |       Durham, NH  03824-3525