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

前端 未结 10 2350
南笙
南笙 2020-12-16 02:49

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 com

相关标签:
10条回答
  • 2020-12-16 03:17

    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.

    0 讨论(0)
  • I don't believe that any general-purpose facility exists for introspection/reflection in C. That's what Java or C# are for.

    0 讨论(0)
  • 2020-12-16 03:21

    You could use Exuberant Ctags to parse your source files instead of using a CPAN module or hacking something up yourself. For instance, for the following code:

    typedef struct _foo {
        int a;
        int b;
    } foo;
    

    ctags emits the following:

    _foo    x.c     /^typedef struct _foo {$/;"     s                               file:
    a       x.c     /^    int a;$/;"                m       struct:_foo             file:
    b       x.c     /^    int b;$/;"                m       struct:_foo             file:
    foo     x.c     /^} foo;$/;"                    t       typeref:struct:_foo     file:
    

    The first, fourth, and fifth columns should be enough for you to determine what struct types exist and what their members are. You could use that information to generate a C program that determines how much padding each struct type has.

    0 讨论(0)
  • 2020-12-16 03:23

    If you have access to Visual C++, you can add the following pragma to have the compiler spit out where and how much padding was added:

    #pragma warning(enable : 4820) 
    

    At that point you can probably just consume the output of cl.exe and go party.

    0 讨论(0)
提交回复
热议问题