【问题标题】:How does the typecheck macro from the Linux kernel work?Linux 内核中的类型检查宏是如何工作的?
【发布时间】:2012-05-01 05:13:13
【问题描述】:

Linux 内核 4.16 的文件include/linux/typecheck.h 包含此代码。

#define typecheck(type,x) \
({      type __dummy; \
        typeof(x) __dummy2; \
        (void)(&__dummy == &__dummy2); \
        1; \
}

检查x 是否与参数type 的类型相同。

但我看不懂这行:

 (void)(&__dummy == &__dummy2);

比较两个变量的首地址有何帮助?

【问题讨论】:

    标签: c linux linux-kernel


    【解决方案1】:

    这使用了两个 GCC 扩展——表达式语句 ({ ... }) 和 typeof()。

    1. 扩展的第一行声明了一个名为type的变量。
    2. 扩展的第二行声明了一个与变量或表达式x相同类型的变量。
    3. 第三行比较两个指针,只有当两个虚拟变量的类型匹配时才会匹配,产生指针不匹配警告(或使用-Werror编译时出错)。
    4. 最后一行(包含1)是表达式的值——相当于true。

    因此,如果 x 的类型与命名类型不同,您会收到编译警告/错误。

    示例代码:

    #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);
    }
    

    编译消息:

    $ /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
    $
    

    请注意,因为我没有使用-Werror,所以代码编译为“OK”。输出是:

    int x OK
    double x OK
    

    【讨论】:

    • char buffer_array[10];字符 *buffer_point; typecheck(typeof(&buffer_array), buffer_point) 给出警告“不同指针类型的比较缺少强制转换”。不是 char * 的 &buffer_array 的类型是什么?
    • 给定char buffer_array[10];,&amp;buffer_array的类型是'指向10数组的指针char',或者char (*)[10]。数组不是指针;它们密切相关,但它们不是一回事。
    【解决方案2】:

    将指针与不兼容的类型进行比较是违反约束的,需要编译器发出诊断。请参阅 6.5.9 等式运算符:

    约束

    应满足以下条件之一:

    • 两个操作数都有算术类型;
    • 两个操作数都是指向兼容类型的合格或不合格版本的指针;
    • 一个操作数是指向对象或不完整类型的指针,另一个是指向限定或非限定版本的 void 的指针;或
    • 一个操作数是一个指针,另一个是一个空指针常量。

    和 5.1.1.3 诊断:

    如果预处理翻译单元或翻译单元包含违反任何语法规则或约束的情况,则符合标准的实现应产生至少一个诊断消息(以实现定义的方式标识),即使该行为也明确指定为未定义或实现定义。在其他情况下不需要生成诊断消息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-05-19
      • 2019-05-18
      • 1970-01-01
      • 1970-01-01
      • 2013-05-05
      • 1970-01-01
      相关资源
      最近更新 更多