'How to properly access packed struct members
What is the correct way to access packed struct's members?
struct __attribute__ ((packed)) MyData {
char ch;
int i;
}
void g(int *x); // do something with x
void foo(MyData m) {
g(&m.i);
}
void bar(MyData m) {
int x = m.i;
g(&x);
}
My IDE gives warning/suggestion for foo that I might be accessing misaligned int pointer, which is indeed the case here. My questions are
- Between foo and bar, is one approach better than the other?
- Is it incorrect to access misaligned pointer data but okay to use it to initialize a properly aligned type? (as in bar).
- Should we copy packed struct individual members to properly aligned data structure and then use it? That would imply that for almost every packed data structure there is a non-packed data structure and packed structure remains confined to serialization layer.
Solution 1:[1]
Currently, calling g may assume that x is aligned. This will probably be fine on x86 architectures, but foo might crash on ARM.
Calling it like in bar is not much better than g taking int x. However, it is correct, since the compiler knows that m.i is misaligned, so can generate the code to copy a misaligned int. This does mean that the pointer can't modify the original object (unless you reassign it).
You can also use the type of a misaligned integer:
typedef int __attribute__((aligned(1))) packed_int;
void g(packed_int * x); // do something with x
This can be called directly as g(&m.i). Be warned that it cannot perform aligned access leading to slowdowns on some platforms.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Artyer |
