【GNU笔记】【C扩展系列】用typeof来引用一个类型 Referring to a Type with typeof
用typeof来引用一个类型 Referring to a Type with typeof
引用表达式类型的另一种方法是使用typeof
. 使用这个关键字的语法看起来像sizeof
,但是这个结构在语义上的作用就像用typedef
定义的类型名称。
有两种方法来写typeof
的参数:用表达式或用类型。下面是一个使用表达式的例子。
typeof (x[0](1))
这假设x
是一个指向函数的数组;所描述的类型是函数值的类型。
下面是一个以类型名作为参数的例子。
typeof (int *)
这里描述的类型是指向int的指针。
如果你正在编写一个必须在 ISO C 程序中包含的头文件,请写__typeof__
而不是typeof。参见Alternate Keywords。
typeof
构造可以在任何可以使用typedef名称的地方使用。例如,你可以在声明中、在强制转换中、或在sizeof
或 typeof
中使用它。
当且仅当typeof
是可变修改类型的表达式或该类型的名称时,才会根据其副作用对其操作数进行求值。
typeof
通常与语句表达式一起使用(参见Statement Exprs)。下面是如何将两者结合起来定义一个安全的“ maximum”宏,该宏对任何算术类型都有操作,并且只对每个参数进行一次计算:
#define max(a,b) \
({ typeof (a) _a = (a); \
typeof (b) _b = (b); \
_a > _b ? _a : _b; })
对局部变量使用以下划线开头的名称的原因是为了避免与a
和b
所替代的表达式中出现的变量名称发生冲突。最终我们希望设计一种新形式的声明语法,允许你声明其作用域仅在初始值设定项之后开始的变量;这将是一种更可靠的防止这种冲突的方法。
更多使用typeof
的例子:
-
这里y用x指向的类型声明。
typeof (*x) y;
-
这将y声明为此类值的数组。
typeof (*x) y[4];
-
这将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;
因此,
array (pointer (char), 4)
是指向char
的 4 个指针的数组的类型。
在GNU C中,但不是GNU C++,你也可以将变量的类型声明为__auto_type
。在这种情况下,声明必须只声明一个变量,其声明符必须只是一个标识符,声明必须被初始化,并且变量的类型由初始值设定项决定;只有在初始值设定项之后,变量的名称才在作用域中。(在C++中,你应该使用C++ 11的auto
来实现这个目的。) 使用__auto_type
,上面的 "maximum "宏可以写成:
#define max(a,b) \
({ __auto_type _a = (a); \
__auto_type _b = (b); \
_a > _b ? _a : _b; })
使用__auto_type
而不是typeof
有两个优点:
- 宏的每个参数在宏的展开中只出现一次。这可以防止当对这种宏的调用被嵌套在这种宏的参数中时,宏扩展的大小呈指数增长。
- 如果宏的参数具有可变修改类型,则在使用
__auto_type
时只计算一次,但如果使用typeof
则计算两次 。
[参考资料]
6.7 Referring to a Type with typeof
本文链接:https://blog.csdn.net/u012028275/article/details/119295211