Many C/C++ compilers (including gcc and clang) have a feature called packed structures. It comes in handy for a number of reasons, but it has to be used with caution. One potential pitfall is that you use a pointer to a member of a struct as an argument of another function. Now that function is unaware of the unaligned pointer. Let me illustrate what I mean with some code:
#pragma pack(1)
typedef struct { int x; } uas;
#pragma pack()
void foo(int *f) {
// some code using the value of *f
}
void bar(uas *b) {
foo(&(b->x));
}
The alignment of int
on a 32 bit machine is usually 4. The compiler now may generate code for foo()
that may not work if f
is not 4 byte aligned. This is the case on older ARM architectures.
Now struct uas
and all members within have an alignment guarantee of 1. Clearly, passing the address of b->x
to foo()
is a bad idea.
GCC and clang have a compiler warning (-Wcast-align
) which is triggered, for example, by casting char*
to int*
. Using pointers to members of packed structures, even though supported by both, doesn't seem to trigger this warning. I also tried -Wall
and -Wextra
, but they do not even include -Wcast-align
.
My main question is whether GCC, clang, or any other compiler supporting packed structures have a warning that would be triggered by the particular example above. It seems, such a warning is mandatory if compilers support packed structures.
clang has just added a new -Waddress-of-packed-member
warning for this specific issue. See https://reviews.llvm.org/rL278483 and https://llvm.org/bugs/show_bug.cgi?id=22821 for details. It should appear in the 4.0 release of clang.
gcc has just added the same warning (-Waddress-of-packed-member
) in gcc-9. It is enabled by default when using -Wall
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With