在C代码中使用typeof

Last Updated: 2023-03-05 15:12:45 Sunday

-- TOC --

typeof是gcc对C语言的扩展,用于在编译期间获取变量或表达式的type,灵活使用可以让代码更精炼。typeof使得C语言有一点点动态语言的感觉,Linux内核存在大量使用typeof的macro。

简单来说,typeof用来获取variable或expression的type:

typeof(int *)  // int *
typeof(x[0](1))  // x is an array of pointers to functions

一个示例case:

#define max(a,b) \
       ({ typeof (a) _a = (a); \
           typeof (b) _b = (b); \
         _a > _b ? _a : _b; })

把a和b括起来,是因为它俩可能是表达式,这段代码展开后,通过typeof定义了两个变量_a和_b,然后再做max比较。事先不知道a和b的结果会是什么类型,这有点动态语言的感觉。

想象一下,上面的这段代码,如果没有typeof操作符,应该如何写?会出现很多针对不同类型的max宏,比如int_max,float_max,string_max......

This declares y with the type of what x points to. 申明y的类型,与指向x的指针类型相同。

typeof (*x) y;

This declares y as an array of such values.

typeof (*x) y[4];

This declares y as an array of pointers to characters:

typeof (typeof (char *)[4]) y;

It is equivalent to the following traditional C declaration:

char *y[4];

typedef和typeof一起用:

typedef typeof(expr) T;

在typeof中获取函数的返回值类型,我写了个示例如下:

$ cat test.c
#include <stdio.h>


int kk(int a) {
    printf("a = %d\n", a);
    return 1;
}


int main(void) {
    typeof(kk(2)) b;
    b = kk(3);
    printf("b = %d\n", b);
    return 0;
}
$ gcc test.c
$ ./a.out
a = 3
b = 1     

typeof内的kk必须要有一个参数,但是这个位置kk不会被调用,这是为了表示我们需要的是kk返回值的类型!如果只写kk而没有括号,typeof获取的是kk函数的类型,即 int (*)(int)

最后,typeof不是标准C,Standard C requires compilers to prefix language extensions with a double-underscore (which is also why you should never do so for your own functions, variables, etc.),据说CLang使用__typeof__()

本文链接:https://cs.pynote.net/sf/c/202201181/

-- EOF --

-- MORE --