Is there a way in gcc or clang (or any other compiler) to spit information about whether a struct has holes (memory alignment - wise) in it ?
Thank you.
ps: If
One way of finding such holes without analyzing the source code and without adding checks to it (using offsetof() and the like) would be to extract the symbol/debug information from the object/executable/symbol files with some tool and look at the defined structures and members in them, their offsets and sizes and see if everything adds up. Unions will complicate things, though.
You can detect such "holes" via the offsetof
macro:
#include <stddef.h>
struct test {
char a;
int b;
};
...
printf("%zu", offsetof(struct test, b));
If this prints more than 1
, b
obviously has alignment requirements and the compiler produces a gap in between.
Obviously this happens at runtime, not at compile-time, but you can write a script that produces a similar source file, compiles and runs it before the rest of your project, and then, based on the output you do further decisions on how to build your project.
I don't think any compiler provides a facility to notify you about that.
You could explore this question by writing probe code for a particular struct
using sizeof
and &
; if sizeof
the nth member isn't equal to the address of the next member minus the address of that member, there's a hole.
You can use pahole to output information about holes in structures and optionally attempt packing them.
You may want to read "Poke-a-hole and friends" and the pahole announcement for more information
You need a parser which understands c/c++ structures and includes necessary includes files.
As replied by @roee-gavirel, I think the easier solution is to create a test program to print out the offsets
#include <stdio.h>
#include <stddef.h>
typedef struct tData {
long id; /* 8 bytes */
char name[8]; /* 8 bytes */
float salary; /* 4 bytes */
} tData;
tData d;
int main()
{
size_t s_tData = sizeof(tData);
size_t s_id = sizeof(d.id);
size_t s_name = sizeof(d.name);
size_t s_salary = sizeof(d.salary);
printf("sizeof(tData) = %zu\n\n", sizeof(d));
printf("'id' is at = %3zu occupies %zu bytes\n",
offsetof(tData, id), s_id);
printf("'name' is at = %3zu occupies %zu bytes\n",
offsetof(tData, name), s_name);
printf("'salary' is at = %3zu occupies %zu bytes\n",
offsetof(tData, salary), s_salary);
printf("\n");
if (s_tData != s_id + s_name + s_salary)
printf("There is/are holes\n");
return 0;
}
I Don't know any automatic tool, but this could be helpful example:
#include <stddef.h>
struct test {
typea a;
typeb b;
typec c;
};
int gapB = offsetof(struct test, b) - (offsetof(struct test, a) + sizeof(typea));
int gapC = offsetof(struct test, c) - (offsetof(struct test, b) + sizeof(typeb));
printf("Gap of b:%d/n", gapB);
printf("Gap of c:%d/n", gapC);
*Note: you will have to do so for each two members in your stuck.