[Bug c/51628] __attribute__((packed)) is unsafe in some cases

sven.koehler at gmail dot com gcc-bugzilla@gcc.gnu.org
Thu Nov 2 13:27:00 GMT 2017


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

--- Comment #34 from Sven <sven.koehler at gmail dot com> ---
(In reply to H.J. Lu from comment #32)
> long long is aligned to 4 bytes in struct for i386.

Understood. So the aligned(4) was just added to explicitly restating the
alignment?

Anyhow, the two warnings added by that commit seem unrelated to this issue. The
warnings added check the alignment of variables and members in memory. When
they fall below the given threshold, a warning is issued.

This bug report however is about a different issue. Every member of a packed
struct has an alignment guarantee of 1 - no more than that. However, a regular
int* variable guarantees, when dereferenced, guarantees an alignment of 4 (on
i386 and arm, for example). So the following code should produce a warning:

struct foo
{
  int i;
} __attribute__((packed));

struct foo *x;
int *y = &(x->i);


The issue becomes more obvious with this struct:

struct foo2
{
  char c;
  int i;
} __attribute__((packed));


However, both foo and foo2 only have an alignment guarantee of at most 1, so
also the int member inside both structs has an alignment guarantee of at most
1.

As mentioned in the initial post, gcc will generate the proper machine code to
read an unaligned int (on arm for example) when using x->i directly. However,
when using *y, gcc will assume 4 byte alignment. That is to be expected, hence
gcc should warn about the fact, and the address of a (potentially) unaligned
int is assigned to a regular int* pointer.


More information about the Gcc-bugs mailing list