I recently fixed a bug in which a __declspec(align(64))
member of a struct was misaligned because of the way the memory for the struct was allocated. So, I'm looking a way to work around such situations.
For example, consider the following struct:
struct foo {
__declspec(align(64)) int bar[BAZ_LEN];
int baz;
};
If allocated on the stack, the compiler would take care of the alignment. If allocated via malloc()
, it would not work. This will break the code that accesses bar if it depends on its alignment for performance or correctness reasons (or both).
So, the question is: what is the best way to handle such situations? In my situation struct foo
can be considered opaque for all but 'private' functions of my component.
Clarification/update. Thanks so much for the answers. I should have said this beforehand, but the problem was that the user of my struct allocated a chunk of memory and sliced it into multiple pieces, and one of the middle ones was an array of foo_t
structus. The offset to that array is not constant, so aligning the starting address is not likely to help. I'm looking for a way to allow such usage of my structs while retaining some of the alignment assumptions.
The solution I have in mind right now (have not tried this) is to add a padding member:
struct foo {
__declspec(align(64)) int bar[BAZ_LEN];
int baz;
char padding[64];
};
And than in every function do the following (wrapped in a macro):
void f(foo_t *foo_)
{
foo_t *foo = (foo_t *)(((uintptr_t)foo_ & ~63) + 64);
...
}
This wastes 64 bytes per struct which is not an issue in my case. Since the padding member is never accessed the shift would not cause any segfaults. However this solution adds quite a bit of mental overhead since the alignment has to be sanitized for each public function...