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 there is another way to do it, please do inform me.
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 there is another way to do it, please do inform me.
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
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.
Gimpel's FlexeLint/PClint can do this.
$ cat tst.c
int main (void)
{
struct {
char c;
double d;
short s;
} f = { 1, 2.0, 3 };
return f.c;
}
It will report
$ flexelint -w1 +e95? tst.c
FlexeLint for C/C++ (Unix) Vers. 9.00L, Copyright Gimpel Software 1985-2014
--- Module: tst.c (C)
_
double d;
tst.c 5 Note 958: Padding of 7 byte(s) is required to align member on 8 byte
boundary
_
} f = { 1, 2.0, 3 };
tst.c 7 Note 959: Nominal struct size (18 bytes) is not an even multiple of
the maximum member alignment (8 bytes)
tst.c 7 Note 958: Padding of 6 byte(s) is required to align end of struct on
8 byte boundary
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 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.
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.
pahole
et al do –
Thuggee 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;
}
© 2022 - 2024 — McMap. All rights reserved.