variable size structs and diminishing returns

Discussion in 'C Programming' started by David Mathog, Jun 9, 2012.

  1. David Mathog

    David Mathog Guest

    In the EMF graphics file format there are records (for instance,
    EMR_EXTRECREATEPEN) which correspond to structs like this:

    #typedef struct {
    /* bunch of fields */
    uint32_t numEntries; /* number of members in Entries */
    SOMETYPE Entries[1];
    } FIRSTSTRUCT;;

    #typedef struct {
    /* bunch of other fields */
    uint32_t offBmi; /* offset to bitmapinfo from start of record */
    uint32_t cbBmi; /* size of bitmapinfo in bytes */
    uint32_t offBits; /* offset to bitmap from start of record */
    uint32_t cbBits; /* size of bitmap in bytes */
    FIRSTSTRUCT fieldname;
    } SECONDSTRUCT;

    Where the bitmapinfo and bitmap data (also both structs) follow in the
    file record like:
    SECONDSTRUCT <x>bitmapinfo<x>bitmap<x>
    and<x> is optional space which is ignored.

    As far as I can tell the intended benefit of having the Entries[1]
    array within the defining struct is to allow
    the programmer to reference it by name, like:

    FIRSTSTRUCT *data;
    data->Entries = memcpy();

    However, the flip side of that is that it makes calculating the
    offsets for the (optional) bitmap fields in
    the file record a PITA. One cannot just use:

    offBmi = recordinmemory + sizeof(SECONDSTRUCT);

    because SECONDSTRUCT, courtesy of FIRSTSTRUCT is rarely if ever
    sizeof(SECONDSTRUCT) bytes. This results in code like:

    offBmi = sizeof(SECONDSTRUCT) + (data->numEntries-1)*sizeof(SOMETYPE);

    Is this really an improvement over:

    #typedef struct {
    /* bunch of fields */
    uint32_t numEntries; /* number of members in Entries */
    /* SOMETYPE Entries[1]; follows in file record, but is not
    explicitly in the struct */
    } ALTSTRUCT;

    (then define SECONDSTRUCT with ALTSTRUCT, leaving the array out of the
    structs completely, as is
    already the case for the bitmapinfo and bitmaps)

    where

    offBmi = sizeof(SECONDSTRUCT) + data->numEntries*sizeof(SOMETYPE);

    and the variable Entries[] array is to be found at: recordinmemory +
    sizeof(ALTSTRUCT);

    ?

    Why include variable array(s) within the struct using the ARRAY[1]
    notation? Is there some compelling reason to do it that way?

    Thanks,

    David Mathog
     
    David Mathog, Jun 9, 2012
    #1
    1. Advertising

  2. On 2012-06-09, David Mathog <> wrote:
    > In the EMF graphics file format there are records (for instance,
    > EMR_EXTRECREATEPEN) which correspond to structs like this:
    >
    > #typedef struct {
    > /* bunch of fields */
    > uint32_t numEntries; /* number of members in Entries */
    > SOMETYPE Entries[1];
    > } FIRSTSTRUCT;;

    ....
    > Is this really an improvement over:
    >
    > #typedef struct {
    > /* bunch of fields */
    > uint32_t numEntries; /* number of members in Entries */
    > /* SOMETYPE Entries[1]; follows in file record, but is not
    > explicitly in the struct */
    > } ALTSTRUCT;

    ....
    > Why include variable array(s) within the struct using the ARRAY[1]
    > notation? Is there some compelling reason to do it that way?


    Besides the obvious thing of being able to refer to it by name, there is
    at least the reason that the compiler will make sure that the "Entries"
    member is properly aligned for SOMETYPE. That is not necessarily the
    case for malloc(...)+sizeof(ALTSTRUCT).

    A C99 "flexible array member" (which does not count in sizeof of the
    structure type) would possibly be the optimal solution, were C99 support
    universal. (Or even existed at the time the structures above were
    defined.)

    --
    Heikki Kallasjoki
     
    Heikki Kallasjoki, Jun 9, 2012
    #2
    1. Advertising

  3. David Mathog

    David Mathog Guest

    On Jun 9, 2:27 am, Heikki Kallasjoki <> wrote:

    > Besides the obvious thing of being able to refer to it by name, there is
    > at least the reason that the compiler will make sure that the "Entries"
    > member is properly aligned for SOMETYPE.  That is not necessarily the
    > case for malloc(...)+sizeof(ALTSTRUCT).


    OK, alignment is a good reason. Referring by name may not even work
    though, for instance
    there are other structs like for EMR_POLYPOLYLINE (not sure how stable
    this link will be)

    http://msdn.microsoft.com/en-us/library/dd162568(v=vs.85).aspx

    where the struct ends in:
    DWORD aPolyCounts[1];
    POINTL aptl[1];

    Hard to imagine the situation where aptl could ever be successfully
    referenced by name when aPolyCounts is
    also used.

    >
    > A C99 "flexible array member" (which does not count in sizeof of the
    > structure type) would possibly be the optimal solution, were C99 support
    > universal.


    I thought that structs including flexible array members were not
    allowed to be members of other structs (or used in arrays, not that
    that applies here). Otherwise flexible array members would be good
    here because sizeof() would ignore the variable array on the end.

    Basically the problem is that since the run time data structure in
    memory (or on disk) looks like:

    <struct1><variable length field(s)><struct2><variable length
    field(s)>

    there really is no way at compile time to reliably reference anything
    but the members of struct1 by name using a pointer to the beginning of
    this data assembly. (And then only if there aren't 2 arrays on the
    end of struct1!) The compiler can generate name references to members
    of struct2, but only with reference to a new memory pointer to the
    beginning of that struct, and that pointer must be constructed at run
    time.

    Tnanks,

    David Mathog
     
    David Mathog, Jun 9, 2012
    #3
    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. Patricia  Van Hise

    structs with fields that are structs

    Patricia Van Hise, Apr 5, 2004, in forum: C Programming
    Replies:
    5
    Views:
    642
    Al Bowers
    Apr 5, 2004
  2. Chris Hauxwell

    const structs in other structs

    Chris Hauxwell, Apr 23, 2004, in forum: C Programming
    Replies:
    6
    Views:
    561
    Chris Hauxwell
    Apr 27, 2004
  3. Paminu
    Replies:
    5
    Views:
    645
    Eric Sosman
    Oct 11, 2005
  4. Daniel Rudy
    Replies:
    15
    Views:
    1,407
    Keith Thompson
    Apr 10, 2006
  5. Tuan  Bui
    Replies:
    14
    Views:
    478
    it_says_BALLS_on_your forehead
    Jul 29, 2005
Loading...

Share This Page