How can I print the result of sizeof() at compile time in C?

后端 未结 12 1364
星月不相逢
星月不相逢 2020-11-29 20:47

How can I print the result of sizeof() at compile time in C?

For now I am using a static assert (home brewed based on other web resources) to compare the sizeof() re

12条回答
  •  余生分开走
    2020-11-29 21:23

    Duplicate case constant is a trick that is guaranteed to work IN ALL C COMPILERS regardless of how each of them reports error. For Visual C++, it is simple:

    struct X {
        int a,b;
        int c[10];
    };
    int _tmain(int argc, _TCHAR* argv[])
    {
        int dummy;
    
        switch (dummy) {
        case sizeof(X):
        case sizeof(X):
            break;
        }
        return 0;
    }
    

    Compilation result:

     ------ Build started: Project: cpptest, Configuration: Debug Win32 ------
     cpptest.cpp c:\work\cpptest\cpptest\cpptest.cpp(29): error C2196: case value '48' already used
     ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
    

    So sizeof the struct X is 48

    EDITED (3jun2020): For gcc or any other compilers that only print "duplicate case value", I use this trick to narrow down the value:

    1) add a case value 1==2 (to represent false)

    2) by trial and error, narrow down the value e.g. I try to guess the sizeof(X) is >16:

    #include 
    typedef struct _X {
        int a;
        char b[10];
    } X;
    int main()
    {
        printf("Hello World");
    
        int dummy=0   ;
        switch (dummy) {
        case  1==2:
        case sizeof( X)>16:
        //case 16:
        break;
        }
        return 0;
    }
    

    result:

    main.c: In function ‘main’:
    main.c:14:5: error: duplicate case value
         case sizeof( X)>16:
         ^~~~
    main.c:13:5: error: previously used here
         case  1==2:
    

    so it is false, i.e. sizeof(X)<=16.

    3) repeat with some other sensible values. e.g. try to guess that it is 16 i.e. sizeof(X)==16. If it doesn't complain about duplicate case value. Then the expression is true.

    4) optionally add a case 16 to verify it e.g.

    #include 
    typedef struct _X {
        int a;
        char b[10];
    } X;
    int main()
    {
        printf("Hello World");
    
        int dummy=0   ;
        switch (dummy) {
       // case  1==2:
        case sizeof( X):
        case 16:
        break;
        }
        return 0;
    }
    

    result

    main.c: In function ‘main’:
    main.c:15:5: error: duplicate case value
         case 16:
         ^~~~
    main.c:14:5: error: previously used here
         case sizeof( X):
    

    confirming that sizeof(X) is 16.

    Alternatively, it is observed that gcc can report multiple duplicates, so this trick is possible for making multiple guesses on a single pass:

    #include 
    typedef struct _X {
        int a;
        char b[10];
    } X;
    int main()
    {
        printf("Hello World");
    
        int dummy=0   ;
        switch (dummy) {
        case  1==2: //represents false
        case 1==1: //represents true
        case sizeof( X)>10:
        case sizeof( X)>12:
        case sizeof( X)>14:
        case sizeof( X)>16:
        case  sizeof( X)==16:
        //case 16:
        break;
        }
        return 0;
    }
    

    result

    main.c: In function ‘main’:
    main.c:14:5: error: duplicate case value
         case sizeof( X)>10:
         ^~~~
    main.c:13:5: error: previously used here
         case 1==1:
         ^~~~
    main.c:15:5: error: duplicate case value
         case sizeof( X)>12:
         ^~~~
    main.c:13:5: error: previously used here
         case 1==1:
         ^~~~
    main.c:16:5: error: duplicate case value
         case sizeof( X)>14:
         ^~~~
    main.c:13:5: error: previously used here
         case 1==1:
         ^~~~
    main.c:17:5: error: duplicate case value
         case sizeof( X)>16:
         ^~~~
    main.c:12:5: error: previously used here
         case  1==2:
         ^~~~
    main.c:18:5: error: duplicate case value
         case  sizeof( X)==16:
         ^~~~
    main.c:13:5: error: previously used here
         case 1==1:
         ^~~~
    

    suggesting the sizeof(X) is >10, >12, >14 but is not >16. The ==16 is added as a final guess.

提交回复
热议问题