C++: Reference to a packed struct field

Viewed 53

GCC forbids taking reference to a field in a packed struct (tested on version 9, -std=gnu++17). However, I notice that if the field were a packed class type itself, it doesn't complain:

struct wrapper {
  uint32_t value;
} __attribute__((packed));

#if 0
using wrapped = wrapper;
#else
using wrapped = uint32_t;
#endif

struct stuff {
  char cfield[1];
  // misaligned
  wrapped ifield;
}  __attribute__((packed));

void receive(wrapper &token) {
  token.value = 101;
}

void receive(uint32_t &token) {
  token = 101;
}

int main() {
  stuff s;
  receive(s.ifield);
  std::cout << sizeof(stuff) << std::endl; // 5
  std::cout << offsetof(stuff, ifield) << std::endl; // 1
  // std::cout << s.ifield.value << std::endl; // 101
  return 0;
}

The code above doesn't compile, objecting to taking reference to ifield of uint32_t type.

With #if 1, however, it compiles and runs OK. Note that the wrapped value is misaligned for a 32-bit integer, as confirmed by the printed messages. But still the update through its reference is successful.

I'm not sure why the second case compiles. Doesn't the same objection in the first case is also present for the second—i.e., referencing a packed member doesn't guarantee alignment?

0 Answers
Related