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.

Reply via email to