In C there’s a common idiom where you define a structure with a zero-length array as the last item. A pointer to such a struct acts like a header for a buffer.
Example from a SoC project:
struct TPropertyTag
{
u32 nTagId;
u32 nValueBufSize;
u32 nValueLength;
u8 ValueBuffer[0];
}
The caller is responsible for allocating the right size of memory, then casting the void *
to a TPropertyTag *
. The advantage is that one struct can handle different sizes that are runtime-known. The obvious disadvantage is the utter lack of type safety.
In this case, interfacing with hardware, I have to use the layout dictated by the SoC, so I don’t have the option to redefine the API.
I’m trying to find a clean and idiomatic way to express this in Zig.
One approach would be to make a struct for each usage of the property tag. This is unwieldy, because there are many different “subtypes” of property tag that each have their own lengths. It’s impractical to define all of those structs, especially since the first 3 fields would be identical across all of them.
I can’t find a way to declare an array of unknown size. A many-item pointer doesn’t seem to do the job, since the memory layout needs to put the buffer immediately after the header.
Does anyone have a good example of this usage in Zig?