D
David Mathog
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
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