另一种引用一个表达式类型的方法就是使用typeof,使用这个关键字的语法看上去有点像使用sizeof,但从本质上讲,它更像是使用typedef定义一个类型名称。
可以使用表达式或是一个类型名来引用类型。比如下面是一个使用表达式的例子:
typeof (x[0](1))
这里假设x是一个指向多个函数的指针数组。这里得到的类型实际是函数值的类型。
下面是一个使用类型名的例子:
typeof (int *)
这里得到的类型是指向int型的指针。
如果你要把typeof写在头文件中,而且这些头文件是要用在ISO C程序中,那么应该写成__typeof__而不是typeof
typeof能被用在任何需要引用类型名的情况下,比如你可以用在声明、显示类型转换(cast)或是在sizeof和typeof内使用。
typeof在协助内嵌表达式的声明时非常有用。这里演示一个如何定义一个安全(在任何情况下,各参数只会被计算一次)的求最大值的宏。
#define max(a,b)
({
typeof (a) _a = (a);
typeof (b) _b = (b);
_a > _b ? _a : _b;
})
让局部变量名以下划线开关的原因是避免与内嵌表达式被使用时传进来的参数名相冲突。我们更希望建立一种新的语法规则,按照这种语法规则,声明的变量的作用域只在该变量初始化之后。相信这会是一种更加可靠的避免冲突的方法。
一些别的使用typeof的例子:
1、y的类型与x所指向的类型相同
typeof (*x) y;
2、 y的类型是指向字符的指针数组
typeof ( typeof (char *) [4]) y;
这与传统C的方法char *y[4];作用相同
来看看使用typeof声明的意义以及为什么说它很用:
#define pointer(T) typeof (T *)
#define array(T, N) typeof(T [N])
于是声明就可以写成以下形式:
array (pointer (char), 4) y;
因此y的类型就是有四个元素、这些元素指向char类型的指针数组。
关于兼容性:在GCC 2中提供了一个更加局限的扩展,这个扩展允许用户使用typedef T = expr;以使T类型与expr类型相同。这个扩展在GCC3.0和3.2版本中会出现问题,在3.2.1及以后的版本中会报错。不过可以用下面的方法来重写:
typedef typeof(expr) T;
这种方法写的代码在所有GCC版本中都可行。
阅读(1634) | 评论(1) | 转发(0) |