1

How can I get a list that contains all my structs after gcc compilers padding? Let's say my code contains the following struct:

typedef struct{
   char a;
   int b;
} struct_i;

The wished output is(for all structes in my code):

typedef struct{
char a;
char padding[3];
int b;
} struct_i;

The purpose is analysis, maybe consider structure members rearrangement that will reduce memory that used for padding.

David
  • 733
  • 2
  • 11
  • 30
  • 5
    Sidenote: You should avoid write code that depends on specific structure padding or layout. Such code tends to be very fragile and non-portable. – user694733 Feb 19 '18 at 14:23
  • What you want to do for this `padding`? – llllllllll Feb 19 '18 at 14:28
  • Related, (or maybe even duplicate): https://stackoverflow.com/q/9780850/694733 – user694733 Feb 19 '18 at 14:28
  • 1
    Not sure why it matters. It is doing that so 16 bit values are on 16 bit boundaries (addresses), 32 bit values are on 32 bit boundaries, etc. You can get rid of padding by "packing" it with: "__attribute__ ((aligned (1)))", however that may cause boundary access problems. – Marker Feb 19 '18 at 14:35
  • 1
    +1 for non-portable. It might end up being processor dependent. Intel's Performance Primitives library used to implement 16- or 32-bit aligned pointers, but only for Intel chips (it'd run on other chips but not guaranteed alignment). – Pam Feb 19 '18 at 14:41
  • You can't get this list automatically - it's not something that would be dumped by default. If you compile with debug information, though, you should be able to read the padding through that programatically. – Anya Shenanigans Feb 19 '18 at 14:49
  • 1
    Look up the `pahole` utility from the "7 dwarves" project. It reads debuginfo and tells you information about holes. Also, in very new versions of gdb, you can use the `/o` flag to `ptype` to see this as well. – Tom Tromey Feb 19 '18 at 15:01

1 Answers1

2

Only a partial answer: If you are interested in the information only (without the ability to feed the structure back), you can use clang with the following option:

clang -c my prog.c -Xclang -fdump-record-layouts

E.g., the following code

#include <stdio.h>
struct foo{
 char c;
 int  i;
};

int main()
{
  struct foo bar = {'a',42};
  printf("%d\n%d\n",(int)bar.c,bar.i);

  return 0;
}

produces

 > clang -c foo.c -Xclang -fdump-record-layouts

 *** Dumping AST Record Layout

          0 | struct foo
          0 |   char c
          4 |   int i
            | [sizeof=8, align=4]

 *** Dumping IRgen Record Layout Record: RecordDecl 0x7f80fe0a47e0 <foo.c:2:1, line:5:1> line:2:8 struct foo definition |-FieldDecl
 0x7f80fe0a48a0 <line:3:2, col:7> col:7 referenced c 'char' `-FieldDecl
 0x7f80fe0a4900 <line:4:2, col:7> col:7 referenced i 'int'

 Layout: <CGRecordLayout   
    LLVMType:%struct.foo = type { i8, i32 }  
    IsZeroInitializable:1   
    BitFields:[ 
 ]>
Matthias
  • 8,018
  • 2
  • 27
  • 53