> On Aug 10, 2023, at 2:58 AM, Martin Uecker <muec...@gwdg.de> wrote: > > Am Mittwoch, dem 09.08.2023 um 20:10 +0000 schrieb Qing Zhao: >> >>> On Aug 9, 2023, at 12:21 PM, Michael Matz <m...@suse.de> wrote: > > ... >> >> By definition, the sizeof() of a struct with FAM might not be the same as >> the non-FAM one. >> i.e, for the following two structures, one with FAM, the other with fixed >> array: >> >> struct foo_flex { int a; short b; char t[]; } x = { .t = { 1, 2, 3 } }; >> struct foo_fix {int a; short b; char t[3]; } >> >> With current GCC: >> sizeof(foo_flex) == 8 >> sizeof(foo_fix) == 12 >> >> I think that the current behavior of sizeof for structure with FAM in GCC is >> correct. > > Yes, sadly the sizeof has to be like this as required by ISO C. Agreed. Yes, if the size information of the FAM can be integrated into the TYPE system in C standard, we will not have such issue anymore.
> >> >> The major issue is what was pointed out by Martin in the previous email: >> >> Whether using the following formula is correct to compute the allocation? >> >> sizeof(struct foo_flex) + N * sizeof(foo->t); > > That formula is safe for allocation, but might allocate more padding > than the minimum amount and Yes. > it might allocate less storage than a > similar array with fixed array. Yes. > >> As pointed out in the wikipedia, the value computed by this formula might >> be bigger than the actual size since “sizeof(struct foo_flex)” might >> include >> paddings that are used as part of the array. >> >> So the more accurate formula should be >> >> offset(struct foo_flex, t[0]) + N * sizeof(foo->t); >> >> With GCC, offset(struct foo_flex,t[0]) == 6, which is also correct. > > This formula might be considered incorrect / dangerous because > it might allocate less storage than sizeof(struct foo_flex). > > > https://godbolt.org/z/8accq75f3 I see, thanks. >> > ... >>> As in: I think sizeof for both structs should return 12, and 12 bytes >>> should be reserved for objects of such types. >>> >>> And then the next question is what __builtin_object_size should do with >>> these: should it return the size with or without padding at end (i.e. >>> could/should it return 9 even if sizeof is 12). I can see arguments for >>> both. >> >> Currently, GCC’s __builtin_object_size use the following formula to compute >> the object size for >> The structure with FAM: >> >> offset(struct foo_flex, t[0]) + N * sizeof(foo->t); >> >> I think it’s correct. >> >> I think that the users might need to use this formula to compute the >> allocation size for a structure with FAM too. > > I am not sure for the reason given above. The following > code would not work: > > struct foo_flex { int a; short b; char t[]; } x; > x.a = 1; > struct foo_flex *p = malloc(sizeof(x) + x.a); > if (!p) abort(); > memcpy(p, &x, sizeof(x)); // initialize struct > Okay. Then, the user still should use the sizeof(struct foo_flex) + N * sizeof(foo->t) for the allocation, even though this might allocate more bytes than necessary. (But this is safe) Let me know if I still miss anything. Thanks a lot for the explanation. Qing > Martin > > >