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

前端 未结 4 2042
逝去的感伤
逝去的感伤 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:35

    Here are three possible solutions.

    The first one will work with any type whose size is less than 256. On my system, it takes about 0.04s (since it doesn't need headers or libraries other than the basic runtime). One downside is that it will only do one at a time, because of the small size of the output channel. Another problem is that it doesn't compensate for slow linking on some systems (notably MinGW):

    howbig() {
      gcc -x c - <<<'int main() { return sizeof ('$*'); }' && ./a.out
      echo $?
    }
    
    $ time howbig "struct { char c; union { double d; int i[3];};}" 
    24
    
    real    0m0.041s
    user    0m0.031s
    sys     0m0.014s
    
    $ time howbig unsigned long long
    8
    
    real    0m0.044s
    user    0m0.035s
    sys     0m0.009s
    

    If you wanted to be able to do larger types, you could get the size one byte at a time, at the cost of a couple more centiseconds:

    howbig2 () 
    { 
        gcc -x c - <<< 'int main(int c,char**v) {
                          return sizeof ('$*')>>(8*(**++v&3)); }' &&
        echo $((0x$(printf %02x $(./a.out 3;echo $?) $(./a.out 2;echo $?) \
                                $(./a.out 1;echo $?) $(./a.out 0;echo $?)) ))
    }
    
    $ time howbig2 struct '{double d; long long u[12];}([973])'
    101192
    
    real    0m0.054s
    user    0m0.036s
    sys     0m0.019s
    

    If you are compiling for x86, the following will probably work, although I'm not in a position to test it thoroughly on a wide variety of architectures and platforms. It avoids the link step (notoriously slow on MinGW, for example), by analyzing the compiled assembly output. (It would probably be slightly more robust to analyze the compiled object binary, but I fear that binutils on MinGW are also slow.) Even on Ubuntu, it is significantly faster:

    howbig3 () { 
      gcc -S -o - -x c - <<< 'int hb(void) { return sizeof ('$*'); }' |
      awk '$1~/movl/&&$3=="%eax"{print substr($2,2,length($2)-2)}'
    }
    
    $ time howbig3 struct '{double d; long long u[12];}([973])'
    101192
    
    real    0m0.020s
    user    0m0.017s
    sys     0m0.004s
    

提交回复
热议问题