Compiler Warning when using Pointers to Packed Structure Members

Sven picture Sven · Mar 4, 2015 · Viewed 9.9k times · Source

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.

Answer

NickBroon picture NickBroon · Sep 5, 2016

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.