How does the typecheck macro from the Linux kernel work?

前端 未结 2 1470
眼角桃花
眼角桃花 2020-12-31 04:38

The file include/linux/typecheck.h of the Linux kernel 4.16 contains this code.

#define typecheck(type,x) \\
({      type __dummy; \\
        ty         


        
相关标签:
2条回答
  • 2020-12-31 05:15

    This uses two GCC extensions — expression statements ({ ... }) and typeof().

    1. The first line of the expansion declares a variable of the named type type.
    2. The second line of the expansion declares a variable of the same type as the variable or expression x.
    3. The third line compares the two pointers, which will only match if the types of the two dummy variables match, generating a pointer mismatch warning (or error if compiling with -Werror).
    4. The last line (containing the 1) is the value of the expression — equivalent to true.

    So, you get a compilation warning/error if the type of x is not the same as the named type.

    Example code:

    #include <stdio.h>
    
    #define typecheck(type,x) \
    ({      type __dummy; \
            typeof(x) __dummy2; \
            (void)(&__dummy == &__dummy2); \
            1; \
    })
    
    int main(void)
    {
        int x;
        if (typecheck(int, x))
            printf("int x OK\n");
        if (typecheck(double, x))
            printf("double x OK\n");
        return(0);
    }
    

    Compilation message:

    $ /usr/bin/gcc -O3 -g -std=gnu99 -Wall -Wextra xx.c -o xx  
    xx.c: In function ‘main’:
    xx.c:15: warning: comparison of distinct pointer types lacks a cast
    $
    

    Note that because I did not use -Werror, the code compiled 'OK'. The output was:

    int x OK
    double x OK
    
    0 讨论(0)
  • 2020-12-31 05:19

    Comparing pointers with incompatible types is a constraint violation and requires the compiler to issue a diagnostic. See 6.5.9 Equality operators:

    Constraints

    One of the following shall hold:

    • both operands have arithmetic type;
    • both operands are pointers to qualified or unqualified versions of compatible types;
    • one operand is a pointer to an object or incomplete type and the other is a pointer to a qualified or unqualified version of void; or
    • one operand is a pointer and the other is a null pointer constant.

    and 5.1.1.3 Diagnostics:

    A conforming implementation shall produce at least one diagnostic message (identified in an implementation-defined manner) if a preprocessing translation unit or translation unit contains a violation of any syntax rule or constraint, even if the behavior is also explicitly specified as undefined or implementation-defined. Diagnostic messages need not be produced in other circumstances.

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