A field in a packed struct will often not have the normal alignment for its type. So taking the address of such a field may yield a misaligned pointer, but gcc does not warn about that. This is similar to casting a pointer from a less aligned type to a more aligned type, which does give a warning (with -Wcast-align). Example: > cat aopf.c #include <stdio.h> void __attribute__((noinline)) f(int *p) { printf("%p\n", p); } struct s { int x; char c; } __attribute__((__packed__)); struct s A[10]; int main(void) { unsigned int i; for (i = 0; i < sizeof(A)/sizeof(A[0]); ++i) { f(&A[i].x); f((int*)(char*)&A[i].x); } return 0; } > gcc -Wall -Wextra -Wcast-align -O aopf.c aopf.c: In function 'main': aopf.c:21:4: warning: cast increases required alignment of target type Ideally both calls to f() should trigger alignment warnings.
To whomever will fix this: beware not to introduce warnings for targets where the "packed" layout is the default. (As has happened in the past for other "packed warnings".)
Confirmed.
Created attachment 28481 [details] Another testcase Testcase which demonstrates more issues.
Gcc does warn (actually it even errs) if you try to pass unaligned variable by reference but does not do this when you use pointers: $ g++ -Wall -c pack_warns.cpp pack_warns.cpp:22:9: error: cannot bind packed field 't->Test::x' to 'float&' Also it'll fail to warn if you use #pragma pack instead of __attribute__((packed)): $ g++ -Wall -c -DUSE_PRAGMA pack_warns.cpp # Compiles wo warnings Just wanted to mention that users frequently run into errors with unaligned data (especially on targets where it really matters e.g. on ARM) so this might be important issue.
*** Bug 79918 has been marked as a duplicate of this bug. ***
*** Bug 54032 has been marked as a duplicate of this bug. ***
Starting with version 9 GCC diagnoses both calls in the test case in comment #0 (the test case with #pragma pack in comment #3 is not diagnosed): $ cat pr41809.c && gcc -O2 -S -Wall pr41809.c void f(int *); struct s { int x; char c; } __attribute__((__packed__)); struct s A[10]; int main(void) { for (int i = 0; i != sizeof(A)/sizeof(A[0]); ++i) { f(&A[i].x); f((int*)(char*)&A[i].x); } } pr41809.c: In function ‘main’: pr41809.c:13:11: warning: taking address of packed member of ‘struct s’ may result in an unaligned pointer value [-Waddress-of-packed-member] 13 | f(&A[i].x); | ^~~~~~~ pr41809.c:14:11: warning: taking address of packed member of ‘struct s’ may result in an unaligned pointer value [-Waddress-of-packed-member] 14 | f((int*)(char*)&A[i].x); | ^~~~~~~~~~~~~~~~~~~~
Let me resolve the attribute subset of the problem as fixed. The outstanding #pragma pack subset is the subject of pr68160.