On Thu, Oct 01, 2020 at 09:34:37AM -0700, Linus Torvalds wrote: > On Wed, Sep 30, 2020 at 4:18 PM Luc Van Oostenryck > <luc.vanoostenryck@xxxxxxxxx> wrote: > > > > If some padding is added because of the presence of a flexible > > array member, the size of the structure will be greater than > > the offset of this flexible array which can cause some > > problems if the assumption is made that these 2 size must be > > identical (which is easy to do since such flexible arrays are > > conceptually 'after' the structure itself). > > The warning seems pointless, and the explanation above is wrong. > > Flexible array padding is normal and good. IOW, if you have > > struct odd_struct { > char c; > unsigned int flex[]; > }; > > then the flexible array - and the structure - very much should be > aligned on 'unsigned int', and both the offset of the flex-array and > the (bogus) size of the structure is 4. > > So this is a normal case and nothing wrong with it, and the above is > the "flexible array caused padding" one (but sizeof and offsetof > match). > > And the case that causes sizeof() and offsetof() to not match is > normal too: but is not that the flexible array member caused padding, > but that *other* members did. > > IOW, maybe you have a structure like this: > > struct other { > uint64_t a; > uint32_t b; > char flex[]; > }; > > and now "offsetof(flex)" is 12, but "sizeof(struct other)" is 16, > because the flex-array itself has no real alignment requirement and > will just be laid out after the 12 bytes of a/b, but the structure has > 8-byte alignment due to 'a'. > > So I don't think the warning is interesting, because this is a > perfectly normal condition too. > > And I don't think your explanation for the warning makes sense, > because you say "padding is added because of the presence of a > flexible array member", but that's not at all what is going on. The > padding is added because of *other* members. Yes, my explanation is completely wrong. The warning is indeed just about sizeof() != offset() and I added because it seemed odd to me but ... > Anyway, the above is just an example of why "sizeof()" itself makes no > sense on these things. A "sizeof()" of a structure with a flexible > array member is inherently pointless. You can't use it for anything > really valid, and it doesn't have any sensible meaning. > > But I don't think that has anything to do with warning about padding. > The padding is right - it's the sizeof() itself that is nonsensical. Yes, indeed, it's perfectly normal. I'll drop this patch. > So in the kernel, we would > > - start warning about 'sizeof(flex_struct)' Adding this warning by default annoys me slightly because it will add 5700+ warnings to the 18000 already present and I think sparse is already underused because it is very/too noisy. But I guess that most occurrences come from a few macros and thus should be easy to get rid off. > - make our "struct_size(s, m, N)" construct use > "offsetof(m)+N*sizeof(*m)" instead of using sizeof(). This accounts for only 432 occurences of sizeof(flex-array), leaving 5287 other ones. > Of course, it may well be that we end up with trouble just because we > end up _needing_ sizeof() for some reason. I can't think of any sane > situation off the top of my head, but who knows what odd macros etc we > might have that end up doing sizeof() as part of things.. Well, yes, for my part, I find the number of nested flexible arrays a bit worrying and much less sensical than the sizeof but .. live and see. -- Luc