Alex Rivera | Logout

A way to find the size and location of padding in a struct?

Asked 2010-07-20T20:18:27.890
11

I'm trying to write a tool that will take as input some C code containing structs. It will compile the code, then find and output the size and offset of any padding the compiler decides to add to structs within it. This is pretty straightforward to do by hand for a known struct using offsetof, sizeof, and some addition, but I can't figure out an easy way to do it automatically for any input struct.

If I knew how to iterate through all elements in a struct, I think I could get the tool written with no problems, but as far as I know there's no way to do that. I'm hoping some StackOverflow people will know a way. However, I'm not stuck in my approach, and I'm certainly open to any alternate approaches to finding padding in a struct.

Edit
Report

2 Answers

2

Have your tool parse the struct definition to find the names of the fields, then generate C code that prints a description of the struct padding, and finally compile and run that C code. Sample Perl code for the second part:

printf "const char *const field_names[] = {%s};\n",
       join(", ", map {"\"$_\""} @field_names);
printf "const size_t offsets[] = {%s, %s};\n",
       join(", ", map {"offsetof(struct $struct_name, $_)"} @field_names),
       "sizeof(struct $struct_name)";
print <<'EOF'
for (i = 0; i < sizeof(field_names)/sizeof(*field_names); i++) {
    size_t padding = offsets[i+1] - offsets[i];
    printf("After %s: %zu bytes of padding\n", field_names[i], padding);
}
EOF

C is very difficult to parse, but you're only interested in a very small part of the language, and it sounds like you have some control over your source files, so a simple parser should do the trick. A search of CPAN turns up Devel::Tokenizer::C and a few C:: modules as candidates (I know nothing about them other than their names). If you really need an accurate C parser, there is Cil, but you have to write your analysis in Ocaml.

answered 2010-07-20T21:28:15.070
2
answered 2010-07-20T21:29:21.437

Your Answer