|
|
|
|
|
by gandalf013
4515 days ago
|
|
A more correct version might be: #include <stddef.h>
int buf_offset = (int)offsetof(struct sdshdr, buf);
struct sdshdr *sh = s - buf_offset;
This is because the compiler might insert padding between your struct elements and the flexible array member. In your case, you're using only int types in the header, so padding shouldn't be an issue on most architectures, but consider the following: struct header {
int i;
char c;
char data[];
};
sizeof(struct header) on my machine is 8, but "data" starts at an offset of 5 from the beginning of the struct. So, to go from "data" pointer to the pointer representing the beginning of the struct, you will need to subtract 5, not 8. Here is a test program: #include <stdio.h>
#include <stddef.h>
struct header {
int i;
char c;
char data[];
};
int main(void)
{
struct header h = {0};
printf("offsetof %zu\n", offsetof(struct header, data));
printf("sizeof %zu\n", sizeof h);
printf("start %p, data start %p, delta %d\n",
(void *)&h, (void *)(h.data), (int)((char *)h.data - (char *)&h));
return 0;
}
http://std.dkuug.dk/JTC1/SC22/WG14/www/docs/n983.htm is relevant for this case as well. |
|
That surprised me. I thought( and read somewhere ) that the flexible array member comes right after the entire struct, which includes possible padding.
OP got away with it since he always allocates the size of the entire struct, which is 8, plus the string size. And since char doesn't have any alignment requirements it doesn't matter, because he always gets back to correct offset. So data member is basically not used, and if you check the code you will see that it actually in never used!