https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89519
Bug ID: 89519
Summary: POD data member fails to be packed; G++ incorrectly
claims it is non-POD
Product: gcc
Version: 8.3.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: gcc at mattwhitlock dot name
Target Milestone: ---
/* === BEGIN TEST CASE === */
#include <type_traits>
class S {
int i;
};
struct P {
char c;
S s;
} __attribute__ ((packed));
static_assert(std::is_pod<S>::value, "S should be a POD type");
static_assert(sizeof(P) == sizeof(char) + sizeof(S), "P should be packed");
/* === END TEST CASE === */
$ g++ -c test.cpp
test.cpp:9:4: warning: ignoring packed attribute because of unpacked non-POD
field 'S P::s'
S s;
^
test.cpp:13:25: error: static assertion failed: P should be packed
static_assert(sizeof(P) == sizeof(char) + sizeof(S), "P should be packed");
~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
As you can see, S is indeed a POD type, as evidenced by std::is_pod<S>::value
being true, yet the compiler fails to pack it.
This may be due to a discrepancy between C++'s definition of a POD type and
G++'s internal concept of "POD for the purpose of layout," as explained in Bug
83732 Comment 3.
Workaround: changing the access control of S::i to public (for example by
changing "class S" to "struct S") makes G++ pack P::s correctly. However, this
should not be necessary, as the standard only requires all non-static data
members in a standard-layout type to have the *same* access control, which need
not be public.