https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84031

            Bug ID: 84031
           Summary: structured binding unpacks nameless padding bitfields
           Product: gcc
           Version: 7.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: will at dash dot org
  Target Milestone: ---

In g++ >= 7.1.0 nameless bitfields are unpacked in structured binding
declarations.
GCC compiles this code with no error or warning.

using uint8_t = unsigned char;

struct bits8 { uint8_t :1, b1:1, b23:2, :1, b567:3; };
static_assert(sizeof(bits8)==1);

int main()
{
    static constexpr bits8 byte{1,2,3};
    const auto& [b0,b1,b23,b4,b567] = byte;
    static_assert(b1==1 && b23==2 && b567==3);
    static_assert(b0==0 && b4==0);
}

Clang, on the other hand, does not accept this code - it chooses not to unpack
nameless bitfields (Clang error: type 'const bits8' decomposes into 3 elements,
but 5 names were provided).

GCC errors on this code which clang accepts:

int main()
{
    static constexpr bits8 byte{1,2,3};
    const auto& [b1,b23,b567] = byte;
    static_assert(b1==1 && b23==2 && b567==3);
}

GCC error: only 3 names provided for structured binding
     const auto& [b1,b23,b567] = byte;
                 ^~~~~~~~~~~~~
note: while 'const bits8' decomposes into 5 elements

I believe that g++ behavior is incorrect. The intent is for the binding
declarations to match identifiers. This interpretation is symmetrical with the
braced-init-list where at most 3 values can be specified to initialize only the
named bitfield members. The nameless ones are passed over...

Reply via email to