开发者

zero length arrays [duplicate]

开发者 https://www.devze.com 2023-02-04 21:47 出处:网络
This question already has answers here: What's the need of array with zero elements? (5 answers) Closed 5 years ago.
This question already has answers here: What's the need of array with zero elements? (5 answers) Closed 5 years ago.

Recently I came across a structure definition,

开发者_如何学运维
struct arr {
    int cnt;
    struct {
        int  size;
        int *name;
    } list[0];
};

and now I don't know the reason for list[0] being declared. What I am interested in is why is this used. Does it have any advantage? If yes, what is it?


The use is for dynamic-length arrays. You can allocate the memory using malloc(), and have the array reside at the end of the structure:

struct arr *my_arr = malloc(sizeof *my_arr + 17 * sizeof *my_arr->list);
my_arr->cnt = 17;
my_arr->list[0].size = 0;
my_arr->list[1].name = "foo";

Actually being able to use 0 for the length is (as pointed out in a comment) a GCC extension. In C99, you can leave out the size literal altogether for the same effect.

Before these things were implemented, you often saw this done with a length of 1, but that complicates the allocation a bit since you must compensate when computing the memory needed.


It is called "struct hack". You can search for it on SO or on the Net

http://www.google.com/search?q=struct+hack&sitesearch=stackoverflow.com/questions

Note that formally it is always illegal to declare arrays of size 0 in C. The code you provided formally is not even compilable. Most C compilers will accept 0-sized array declaration as an extension though, specifically because it is often used in "lazy" version of "struct hack" (it can rely on sizeof to determine how much memory to allocate, since 0-sized array supposedly does not affect the total size of the struct).

An arguably better implementation of struct hack uses an array of size 1

struct arr {
    int cnt;
    struct {
        int  size;
        int *name;
    } list[1];
};

It is "better" because it is formally compilable at least. In order to allocate memory for a struct with N elements in the list, standard offsetof macro is used

arr *a = malloc(offsetof(arr, list) + N * sizeof a->list);

In C99 version of the language specification the "struct hack" is supported through size-less array declaration (with empty []), since 0-sized array declarations are illegal in C99 as well.


Another advantage is if your structure describes on-disk/on-network data. If cnt is 0, the data size may only be the length of cnt.

I'm here just to confirm what I dreaded, that list[0] is not valid.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号