The option -Wpacked reports two different warnings: 1. warning: padding struct to align ‘<member name>’ 2. warning: padding struct size to alignment boundary The first warning indicates that the structure can be reordered in such a way as to reduce padding. The second warning simply indicates that the structure is not a multiple of the largest primitive data type and required padding at the end. I find the first warning much more interesting than the second one. Specifically I would like to control them individually using -Werror. If we can add something like -Wpacked-align and -Wpacked-size as additional options (while still preserving the behavior of -Wpacked) I think this would be a valuable addition to GCC.
I just realized that my original message was referring to the wrong option. I meant: -Wpadded I am therefore requesting two new options: -Wpadded-element and -Wpadded-structure Sorry for the confusion.
Note that bug 53514 is essentially the same bug for C++. If I enable -Wpadded I am flooded with "padding struct size to alignment boundary" warnings, which makes it difficult to find the rarer and much more useful "padding struct to align ‘<member name>’" warnings.
*** Bug 53514 has been marked as a duplicate of this bug. ***
This is quite easy to implement. Just add the two new options [*] to common.opt, add EnabledBy(Wpadding) to them, then update the uses of OPT_Wpadded and warn_padded throughout the source code and testsuite, then update doc/invoke.texi. Bootstrap + regression test, submit patch, ping patch until approved by a maintainer. Commit and add a note to gcc-5/changes.html. Easy to do, but someone still needs to do all this work. If you think this is really worth it, please volunteer to do it. Nobody else will. [*] (I like David Stone's proposal of -Wpadded-in-middle and -Wpadded-at-end, but whoever implements it gets to choose the names)
After thinking about this some more, we are not answering the question that splitting it into two warnings is really trying to get at. The first, and most important is not "Is there padding in the middle of the structure", but "Can I rearrange my data members to save space?". -Wwasted-space might be a good name for this warning. I believe in all systems that gcc targets*, the optimal size can be achieved by arranging elements largest to smallest, so we could just compare the size of a theoretical struct with that arrangment and the size of the user's struct. The second thing the user might wonder is "Do I have padding that I cannot resolve by rearranging". This warning can alert the user that a small change in the size of their data types (or possibly moving data into different structures) could have a greater-than-expected size savings. This is more like the current -Wpadded. * A strange system with 4-byte, 3-byte, and 1-byte aligned types could have a more efficient representation by following every 3 with a 1. I am unsure if this is actually valid according to the C or C++ standard. As long as all of the systems just have power-of-two alignment, the largest to smallest works.
(In reply to Manuel López-Ibáñez from comment #4) > This is quite easy to implement. It's not as trivial as one might think. There's some copy-paste code to disable the flag in various places (instead of handling it inside if possible). $ find -name '*.c' | xargs fgrep -nC2 warn_padded ./gcc/config/spu/spu.c-3959- /* We know this is being padded and we want it too. It is an internal ./gcc/config/spu/spu.c-3960- type so hide the warnings from the user. */ ./gcc/config/spu/spu.c:3961: owp = warn_padded; ./gcc/config/spu/spu.c:3962: warn_padded = false; ./gcc/config/spu/spu.c-3963- ./gcc/config/spu/spu.c-3964- layout_type (record); ./gcc/config/spu/spu.c-3965- ./gcc/config/spu/spu.c:3966: warn_padded = owp; ./gcc/config/spu/spu.c-3967- ./gcc/config/spu/spu.c-3968- /* The correct type is an array type of one element. */ -- ./gcc/config/tilegx/tilegx.c-340- /* We know this is being padded and we want it too. It is an ./gcc/config/tilegx/tilegx.c-341- internal type so hide the warnings from the user. */ ./gcc/config/tilegx/tilegx.c:342: owp = warn_padded; ./gcc/config/tilegx/tilegx.c:343: warn_padded = false; ./gcc/config/tilegx/tilegx.c-344- ./gcc/config/tilegx/tilegx.c-345- layout_type (record); ./gcc/config/tilegx/tilegx.c-346- ./gcc/config/tilegx/tilegx.c:347: warn_padded = owp; ./gcc/config/tilegx/tilegx.c-348- ./gcc/config/tilegx/tilegx.c-349- /* The correct type is an array type of one element. */ -- ./gcc/config/tilepro/tilepro.c-292- /* We know this is being padded and we want it too. It is an ./gcc/config/tilepro/tilepro.c-293- internal type so hide the warnings from the user. */ ./gcc/config/tilepro/tilepro.c:294: owp = warn_padded; ./gcc/config/tilepro/tilepro.c:295: warn_padded = false; ./gcc/config/tilepro/tilepro.c-296- ./gcc/config/tilepro/tilepro.c-297- layout_type (record); ./gcc/config/tilepro/tilepro.c-298- ./gcc/config/tilepro/tilepro.c:299: warn_padded = owp; ./gcc/config/tilepro/tilepro.c-300- ./gcc/config/tilepro/tilepro.c-301- /* The correct type is an array type of one element. */ -- ./gcc/fortran/trans-io.c-223- /* -Wpadded warnings on these artificially created structures are not ./gcc/fortran/trans-io.c-224- helpful; suppress them. */ ./gcc/fortran/trans-io.c:225: int save_warn_padded = warn_padded; ./gcc/fortran/trans-io.c:226: warn_padded = 0; ./gcc/fortran/trans-io.c-227- gfc_finish_type (t); ./gcc/fortran/trans-io.c:228: warn_padded = save_warn_padded; ./gcc/fortran/trans-io.c-229- st_parameter[ptype].type = t; ./gcc/fortran/trans-io.c-230-} ./gcc/tree-nested.c-3197- /* In some cases the frame type will trigger the -Wpadded warning. ./gcc/tree-nested.c-3198- This is not helpful; suppress it. */ ./gcc/tree-nested.c:3199: int save_warn_padded = warn_padded; ./gcc/tree-nested.c:3200: warn_padded = 0; ./gcc/tree-nested.c-3201- layout_type (root->frame_type); ./gcc/tree-nested.c:3202: warn_padded = save_warn_padded; ./gcc/tree-nested.c-3203- layout_decl (root->frame_decl, 0); ./gcc/tree-nested.c-3204-
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68901 is an example of missed -Wpadded suppression.
(In reply to krux from comment #6) > (In reply to Manuel López-Ibáñez from comment #4) > > This is quite easy to implement. > > It's not as trivial as one might think. > There's some copy-paste code to disable the flag in various places (instead > of handling it inside if possible). You can still have a global -Wpadded that implies the two new warning options and only warn, for example, if warn_padded && warn_packed_size are both true. Even better would be to mark these types as internal/ARTIFICIAL, look for all places where OPT_Wpadded is used and, if not already done, avoid warning for anything internal /ARTIFICIAL, then remove this hack. This should require no major surgery in the compiler nor any deep knowledge about the code.
It might further be worth giving the "you can rearrange to save sapce" option two warning levels. The highest level would warn for all cases where rearranging can reduce size, and the lowest level would warn for all cases where rearranging only the private data members can reduce size. This is a potentially important point because rearranging public / protected data members can affect the API of your type by changing how it interacts with structured bindings, and, if it is also an aggregate, aggregate construction. The important new consideration that has the potential for a third warning option is the handling of empty types. It could be useful to have a warning that alerts the user that marking a data member with [[no_unique_address]] would reduce the size of their structure. A potential name for this is -Wempty-data-member-wastes-space or -Wmissing-no-unique-address. Cross posted to the equivalent clang bug report: https://bugs.llvm.org/show_bug.cgi?id=22442#c5
(In reply to Aaron S. Kurland from comment #1) > I just realized that my original message was referring to the wrong option. > I meant: -Wpadded > > I am therefore requesting two new options: > > -Wpadded-element and -Wpadded-structure > > Sorry for the confusion. Confirmed, I have wanted a split like this as well. (In reply to Manuel López-Ibáñez from comment #4) > > [*] (I like David Stone's proposal of -Wpadded-in-middle and > -Wpadded-at-end, but whoever implements it gets to choose the names) Those are good name suggestions too.