Macro to Optimize Space for Embedded Array

Discussion in 'C Programming' started by Michael B Allen, Jul 31, 2005.

  1. Let's say I have a stucture with a flexible array at the end:

    struct foo {
    short s;
    char bits[1];
    };

    I would like to embed this in other structures like:

    #define TAILBITS 500

    struct bar {
    int i;
    struct foo f;
    char tail[TAILSIZE(500)];
    };

    My question is, can someone define a macro TAILSIZE that evaluates to
    an optimal value for holding the specified number of bits in foo->bits?

    Like a good poster I have tried this beforehand and came up with the
    following that takes advantage of any padding in the structure:

    #define PAD (sizeof(struct foo) - offsetof(struct foo, bits))
    #define BYTES4BITS(nbits) (((nbits) + 1) / 8)
    #define TAILSIZE(nbits) ((PAD + 1) > BYTES4BITS(nbits) ? 1 : BYTES4BITS(nbits) - PAD)

    At first glance this appears to work but is it legit?

    Thanks,
    Mike
    Michael B Allen, Jul 31, 2005
    #1
    1. Advertising

  2. Michael B Allen

    Michael Mair Guest

    Michael B Allen wrote:
    > Let's say I have a stucture with a flexible array at the end:
    >
    > struct foo {
    > short s;
    > char bits[1];
    > };
    >
    > I would like to embed this in other structures like:
    >
    > #define TAILBITS 500
    >
    > struct bar {
    > int i;
    > struct foo f;
    > char tail[TAILSIZE(500)];
    > };
    >
    > My question is, can someone define a macro TAILSIZE that evaluates to
    > an optimal value for holding the specified number of bits in foo->bits?
    >
    > Like a good poster I have tried this beforehand and came up with the
    > following that takes advantage of any padding in the structure:
    >
    > #define PAD (sizeof(struct foo) - offsetof(struct foo, bits))
    > #define BYTES4BITS(nbits) (((nbits) + 1) / 8)
    > #define TAILSIZE(nbits) ((PAD + 1) > BYTES4BITS(nbits) ? 1 : BYTES4BITS(nbits) - PAD)
    >
    > At first glance this appears to work but is it legit?


    PAD certainly is okay, as is TAILSIZE (even though I might have
    formulated it slightly differently).
    If BYTES4BITS is supposed to return the number of bytes necessary
    to hold a certain number of bits, you have to try again:
    Say you want to hold 9 Bits, then BYTES4BITS tells you one Byte
    was quite enough. I.e. you need
    #define BYTES4BITS(nbits) (((nbits) + 7) / 8)
    or, better yet
    #define BYTES4BITS(nbits) (((nbits) + (CHAR_BIT-1)) / CHAR_BIT)

    Note that there is not guarantee whatsoever that the struct hack
    works in C89 even though it seems to do so (and probably even on
    early versions of the DS9000).


    Cheers
    Michael
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.
    Michael Mair, Aug 1, 2005
    #2
    1. Advertising

  3. On Mon, 01 Aug 2005 08:36:14 +0200, Michael Mair wrote:

    >> #define BYTES4BITS(nbits) (((nbits) + 1) / 8)
    >>

    > If BYTES4BITS is supposed to return the number of bytes necessary
    > to hold a certain number of bits, you have to try again:
    > Say you want to hold 9 Bits, then BYTES4BITS tells you one Byte
    > was quite enough. I.e. you need
    > #define BYTES4BITS(nbits) (((nbits) + 7) / 8)
    > or, better yet
    > #define BYTES4BITS(nbits) (((nbits) + (CHAR_BIT-1)) / CHAR_BIT)


    Ah, right. Thanks.

    Actually the CHAR_BIT thing confuses me a little. I thought char was
    guaranteed to be 8 bits? Are there some little 7 bit micro controllers
    that can only hold 7 bits per char?

    Thanks,
    Mike
    Michael B Allen, Aug 1, 2005
    #3
  4. Michael B Allen

    Ben Pfaff Guest

    Michael B Allen <> writes:

    > Actually the CHAR_BIT thing confuses me a little. I thought char was
    > guaranteed to be 8 bits? Are there some little 7 bit micro controllers
    > that can only hold 7 bits per char?


    char is at least 8 bits. It may be larger.
    --
    "This is a wonderful answer.
    It's off-topic, it's incorrect, and it doesn't answer the question."
    --Richard Heathfield
    Ben Pfaff, Aug 1, 2005
    #4
  5. Michael B Allen

    Tim Rentsch Guest

    Michael B Allen <> writes:

    > Let's say I have a stucture with a flexible array at the end:
    >
    > struct foo {
    > short s;
    > char bits[1];
    > };
    >
    > I would like to embed this in other structures like:
    >
    > #define TAILBITS 500
    >
    > struct bar {
    > int i;
    > struct foo f;
    > char tail[TAILSIZE(500)];
    > };
    >
    > My question is, can someone define a macro TAILSIZE that evaluates to
    > an optimal value for holding the specified number of bits in foo->bits?
    >
    > [...snip proposed definition...]


    (Slight aside: probably better to use 'unsigned char' rather than
    'char' for the bits, since with 'unsigned char' all values are
    guaranteed to be available.)

    In response to the question -- how about finessing the problem
    instead?

    #define BITMAP_STRUCT(n) \
    struct { \
    short s; \
    unsigned char bits[ BYTES_FOR_BITS(n) ]; \
    }

    #define BYTES_FOR_BITS(n) ( ((n) + (CHAR_BIT-1)) / CHAR_BIT)

    ...

    struct bar {
    int i;
    BITMAP_STRUCT( 500 ) f;
    };


    Unless there is a need to deal with 'struct foo' outside
    the context of the other structs where they are embedded,
    this approach seems to avoid all the difficulties.
    Tim Rentsch, Aug 3, 2005
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Dead RAM
    Replies:
    20
    Views:
    1,111
    John Harrison
    Jul 14, 2004
  2. Shuo Xiang

    Stack space, global space, heap space

    Shuo Xiang, Jul 9, 2003, in forum: C Programming
    Replies:
    10
    Views:
    2,886
    Bryan Bullard
    Jul 11, 2003
  3. Christian Seberino
    Replies:
    21
    Views:
    1,651
    Stephen Horne
    Oct 27, 2003
  4. Ian Bicking
    Replies:
    2
    Views:
    1,009
    Steve Lamb
    Oct 23, 2003
  5. Ian Bicking
    Replies:
    2
    Views:
    721
    Michael Hudson
    Oct 24, 2003
Loading...

Share This Page