Shraddha
Shraddha

Reputation: 2579

Use of the construct struct { a[0] } test;

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

Answers (3)

AnT stands with Russia
AnT stands with Russia

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

zneak
zneak

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

Omkant
Omkant

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

Related Questions