Reputation: 2579
I can't guess the use of constructs such as
struct
{
uint64_t offsets[0];
} table;
Please give me some hint with regard to this.
Upvotes: 0
Views: 143
Reputation: 320481
The code you posted is formally invalid. Formally C language does not support arrays of size 0
.
Some compilers (with loose/legacy error checking) allow an array of size zero at the end of the struct, which was sometimes used to implement so called "struct hack". (A better approach would be to use a trailing array of size 1.) However your declaration does not provide for that use. "Struct hack" requires a named struct type, and the actual objects have to be dynamically allocated. In your case the struct type is left unnamed, and the variable table
is defined non-dynamically. So, "struct hack" is out of question here, assuming you reproduced the code correctly.
So, even it it compiles, you end up with variable table
that contains no usable data. The only use for this variable (if declared with static storage duration) is to produce an unique address constant through &table
expression (a pointer of "pointer to an anonymous struct" type).
One way to turn your declaration into something closer to the "struct hack" is to add a typedef
in front of it
typedef struct
{
uint64_t offsets[0];
} table;
However, a "human-generated" struct declaration for a "struct hack" will typically include other data fields before the flexible array declaration (without them there's simply no point in choosing "struct hack" over an ordinary array).
Upvotes: 5
Reputation: 138051
This is a trick that lets you cast a memory block of any size to your pointer type, and make the last array member a variable-length array. Although probably not standard, this works because C arrays are not bounds-checked.
Here's a very simple example demonstrating it:
typedef struct Foo
{
int count;
int array[0];
} Foo;
Foo* foo = (Foo*)malloc(sizeof(Foo) + 5 * sizeof(int));
foo->count = 5;
You can then use the count
field to know the number of valid elements inside the Foo*
. Since, as mentioned above, C arrays are not bounds-checked, neither the compiler nor the runtime will catch that foo->array
has a size of 0 when you try to read or write to it.
Upvotes: 1
Reputation: 9204
You have defined unnamed struct
actually table
is object not a struct
name.
So,If you have this declaration
typedef struct
{
uint64_t offsets[0];
} table;
Or,
struct table
{
uint64_t offsets[0];
} table;
Then ,this is called variable length array (called struct hack).
There is restriction that,It should be the last member of the struct.
For more about it see this article on struct hack
Upvotes: 0