Find holes in C structs due to alignment

后端 未结 7 2571
难免孤独
难免孤独 2021-02-20 18:26

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

相关标签:
7条回答
  • 2021-02-20 18:44

    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.

    0 讨论(0)
  • 2021-02-20 18:45

    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.

    0 讨论(0)
  • 2021-02-20 18:46

    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.

    0 讨论(0)
  • 2021-02-20 18:57

    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

    0 讨论(0)
  • 2021-02-20 18:57

    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;
    }
    
    0 讨论(0)
  • 2021-02-20 18:58

    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.

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