What is the easiest way to find the sizeof a type without compiling and executing code?

前端 未结 4 1941
逝去的感伤
逝去的感伤 2021-01-20 08:04

I wrote a bash script to determine the size of gcc\'s datatypes (e.g. ./sizeof int double outputs the respective sizes of int and

4条回答
  •  情话喂你
    2021-01-20 08:32

    Using nm with no code

    Just make your thing a global variable. nm can report its size.

    // getsize.c
    
    struct foo {
        char str[3];
        short s;     // expect padding galore...
        int i;
    } my_struct;
    

    Compile but don't link, then use nm:

    $ gcc -c getsize.c
    $ nm getsize.o --format=posix
    my_struct C 000000000000000c 000000000000000c
    

    Note that the last column is the size (in hex), here is how we can get it:

    $ nm test.o -P | cut -d ' ' -f 4
    000000000000000c
    
    # or in decimal
    $ printf %d 0x`nm test.o -P | cut -d ' ' -f 4`
    12
    

     

    Using objdump with no code

    If nm doesn't work for some reason, you can store the size itself in a global variable.

    Start with this C file:

    // getsize.c
    struct foo { char str[3]; short s; int i; };
    
    unsigned long my_sizeof = sizeof(struct foo);
    

    Now we have to find the value of this variable from the object file.

    $ gcc -c sizeof.c
    $ objdump -Sj .data sizeof.o
    
    test.o:     file format elf64-x86-64
    
    
    Disassembly of section .data:
    
    0000000000000000 :
       0:   0c 00 00 00 00 00 00 00                             ........
    

    Darn, little endian! You could write a script to parse this, but the following solution (assuming GCC extensions) will force it to always be big endian:

    // getsize.c
    struct foo { char str[3]; short s; int i; };
    
    struct __attribute__ ((scalar_storage_order("big-endian"))) {
        unsigned long v;
    } my_sizeof = { sizeof(struct foo) };
    

    This yields:

    0000000000000000 :
       0:   00 00 00 00 00 00 00 0c                             ........
    

    Watch out! You can't just strip out all non-hex characters because sometimes the "...." stuff on the right will be valid ASCII. But the first one should always be a .. The following command keeps things between the : and the first ..

    $ gcc -c sizeof.c
    $ objdump -Sj .data sizeof.o |
    
            sed '$!d                     # keep last line only
                 s/\s//g                 # remove tabs and spaces
                 s/.*:\([^.]*\)\..*/\1/' # only keep between : and .'
    
    000000000000000c
    

提交回复
热议问题