Newsgroups: comp.lang.c
From: Clive D.W. Feather
Subject: Re: Criticism of C-FAQ submission invited
Date: Thu, 22 Sep 1994 13:08:17 GMT
Message-ID: <CwJ8Hu.8y6@scone.london.sco.com>

In article <35qdf0$7iq@netaxs.com>, Eric Raymond wrote:
> The first member of each
> continuous group of bit fields is typically word-aligned, with all following
> being continuously packed into following words (though ANSI C requires the
> latter only for bit-field groups of less than word size).

False. ISO C (please get the name right) requires that the first bit field be put into some addressable object, but there is no requirement that it be a ``word'' (thus an 11 bit field might be put into a halfword on a 32 bit system). If the following field will fit in the same object it must be put there. If it doesn't it can be overlapped between two objects or put into a new object. Thus:

    int a : 11;
    int b :  2;
    int c : 11;
    int d :  7;

could be packed as:

    32-bit object: a, b, c, d

or as:

    16-bit object: a, b
    16-bit object: c
    16-bit object: d

or as:

    16-bit object: a, b, 3 bits of c
    16-bit object: 8 bits of c, d

> Q: How do I figure the ``true size'' (with trailing padding) of a type when
> it occurs in a struct or array?

In a struct:

    offsetof (structure, next field) - offsetof (structure, field)

or:

    sizeof (structure) - offsetof (structure, last field)

There is no padding in an array.

> A: By rounding up its apparent size to a multiple of its alignment.

Not necessarily. The padding can depend on what is following.

> (assume a 32-bit architecture with normal C sizes
> of long=4, int=4, short=2, and char=1 on all these unless otherwise
> specified).

and assuming pointer=4.

> (4) struct {char *; short; long;} will have a half-word of padding after
> the short

or before it. On big-endian machines it may be easier to access the half-word in the low-order half.

> Q: How can I get complete control of the bit-level layout of a struct?
> A: This is what bit-fields are for. Declare all your members as bit fields.
> The structure may still have invisible trailing padding (unless your last
> bit field exactly fills to the end of the last machine word), but on modern
> architectures this will eliminate all other padding and give you complete
> control of the bit layout of the declared parts (albeit at a significant
> cost in access time). However, ANSI does not guarantee this well-
> behavedness, so look out for snags.

Firstly, there may be padding whenever fields don't fit exactly. Secondly, you still aren't guaranteed the order of the bit-fields within each ``addressable object''.

> On some poorly-implemented C compilers on very old 36-bit word-oriented
> architectures, even this may not be enough; a bit field that runs over
> the end of a word boundary may force the next bit field to start at the
> beginning of the following word, leaving an invisible gap of up to 35 bits.

Or on well-implemented compilers on modern architectures that choose not to go to the effort of splitting bit-fields across word boundaries.

> On these machines, your only option is to declare the struct as a single
> char array and do the field accesses yourself in C.

And you still won't know the ordering of bits within the word relative to the external format you are conforming to. This can't be solved in a strictly conforming manner.

-- 
Clive D.W. Feather     | Santa Cruz Operation    | If you lie to the compiler,
clive@sco.com          | Croxley Centre          | it will get its revenge.
Phone: +44 1923 813541 | Hatters Lane, Watford   |   - Henry Spencer
Fax:   +44 1923 813811 | WD1 8YN, United Kingdom | <= NOTE: NEW PHONE NUMBERS