typeof關(guān)鍵字是C語(yǔ)言中的一個(gè)新擴展。只要可以接受typedef名稱(chēng),Sun Studio C 編譯器就可以接受帶有typeof的結構,包括以下語(yǔ)法類(lèi)別:
編譯器接受帶雙下劃線(xiàn)的關(guān)鍵字:__typeof和__typeof__。本文中的例子并沒(méi)有遵循使用雙下劃線(xiàn)的慣例。從語(yǔ)句構成上看,typeof關(guān)鍵字后帶圓括號,其中包含類(lèi)型或表達式的名稱(chēng)。這類(lèi)似于sizeof關(guān)鍵字接受的操作數(與sizeof不同的是,位字段允許作為typeof實(shí)參,并被解釋為相應的整數類(lèi)型)。從語(yǔ)義上看,typeof 關(guān)鍵字將用做類(lèi)型名(typedef名稱(chēng))并指定類(lèi)型。
下面是兩個(gè)等效聲明,用于聲明int類(lèi)型的變量a。
typeof(int) a; /* Specifies variable a which is of the type int */
typeof('b') a; /* The same. typeof argument is an expression consisting of
character constant which has the type int */
以下示例用于聲明指針和數組。為了進(jìn)行對比,還給出了不帶typeof的等效聲明。
typeof(int *) p1, p2; /* Declares two int pointers p1, p2 */
int *p1, *p2;
typeof(int) * p3, p4;/* Declares int pointer p3 and int p4 */
int * p3, p4;
typeof(int [10]) a1, a2;/* Declares two arrays of integers */
int a1[10], a2[10];
如果將typeof用于表達式,則該表達式不會(huì )執行。只會(huì )得到該表達式的類(lèi)型。以下示例聲明了int類(lèi)型的var變量,因為表達式foo()是int類(lèi)型的。由于表達式不會(huì )被執行,所以不會(huì )調用foo函數。
extern int foo();
typeof(foo()) var;
使用typeof的聲明限制
請注意,typeof構造中的類(lèi)型名不能包含存儲類(lèi)說(shuō)明符,如extern或static。不過(guò)允許包含類(lèi)型限定符,如const或volatile。例如,下列代碼是無(wú)效的,因為它在typeof構造中聲明了extern:
typeof(extern int) a;下列代碼使用外部鏈接來(lái)聲明標識符b是有效的,表示一個(gè)int類(lèi)型的對象。下一個(gè)聲明也是有效的,它聲明了一個(gè)使用const限定符的char類(lèi)型指針,表示指針p不能被修改。
extern typeof(int) b;
typeof(char * const) p = "a";在宏聲明中使用typeof
typeof構造的主要應用是用在宏定義中??梢允褂?tt>typeof關(guān)鍵字來(lái)引用宏參數的類(lèi)型。因此,在沒(méi)有將類(lèi)型名明確指定為宏實(shí)參的情況下,構造帶有所需類(lèi)型的對象是可能的。
另外一篇:
另一種引用一個(gè)表達式類(lèi)型的方法就是使用 typeof ,使用這個(gè)關(guān)鍵字的語(yǔ)法看上去有點(diǎn)像使用 sizeof ,但從本質(zhì)上講,它更像是使用 typedef 定義一個(gè)類(lèi)型名稱(chēng)。
可以使用表達式或是一個(gè)類(lèi)型名來(lái)引用類(lèi)型。比如下面是一個(gè)使用表達式的例子:
typeof (x [0](1))
這里假設 x 是一個(gè)指向多個(gè)函數的指針數組。這里得到的類(lèi)型實(shí)際是函數值的類(lèi)型。
下面是一個(gè)使用類(lèi)型名的例子:
typeof (int *)
這里得到的類(lèi)型是指向 int 型的指針
如果你要把 typeof 寫(xiě)在頭文件中,而且這些頭文件是要用在 ISO C 程序中,那么應該寫(xiě)成 __typeof__ 而不是 typeof
typeof 能被用在任何需要引用類(lèi)型名的情況下,比如你可以用在聲明、顯示類(lèi)型轉換( cast )或是在 sizeof 和 typeof 內使用。
typeof 在協(xié)助內嵌表達式的聲明時(shí)非常有用。這里演示一個(gè)如何定義一個(gè)安全(在任何情況下,各參數只會(huì )被計算一次)的求最大值的宏。
# define max (a ,b )
({
typeof (a ) _a = (a );
typeof (b ) _b = (b );
_a > _b ? _a : _b;
})
讓局部變量名以下劃線(xiàn)開(kāi)關(guān)的原因是避免與內嵌表達式被使用時(shí)傳進(jìn)來(lái)的參數名相沖突。我們更希望建立一種新的語(yǔ)法規則,按照這種語(yǔ)法規則,聲明的變量的作用域只在該變量初始化之后。相信這會(huì )是一種更加可靠的避免沖突的方法。
一些別的使用 typeof 的例子:
1 、 y 的類(lèi)型與 x 所指向的類(lèi)型相同
typeof (*x )y ;
2 、 y 的類(lèi)型是指向字符的指針數組
typeof (typeof (char *) [4])y ;
這與傳統 C 的方法 char *y [4];作用相同
來(lái)看看使用 typeof 聲明的意義以及為什么說(shuō)它很用:
# define pointer (T )typeof (T *)
# define array (T ,N )typeof (T [N ])
于是聲明就可以寫(xiě)成以下形式:
array (pointer (char ), 4)y ;
因此 y 的類(lèi)型就是有四個(gè)元素、這些元素指向 char 類(lèi)型的指針數組。
關(guān)于兼容性:在 GCC 2中提供了一個(gè)更加局限的擴展,這個(gè)擴展允許用戶(hù)使用 typedef T =expr ;以使 T 類(lèi)型與 expr 類(lèi)型相同。這個(gè)擴展在 GCC3.0 和 3.2 版本中會(huì )出現問(wèn)題,在 3.2.1 及以后的版本中會(huì )報錯。不過(guò)可以用下面的方法來(lái)重寫(xiě):
typedef typeof (expr )T ;
這種方法寫(xiě)的代碼在所有 GCC 版本中都可行。
原文: http://gcc.gnu.org/onlinedocs/gcc-4.3.3/gcc/Typeof.html#Typeof
5.6 Referring to a Type with
typeofAnother way to refer to the type of an expression is with
typeof. The syntax of using of this keyword looks likesizeof, but the construct acts semantically like a type name defined withtypedef.There are two ways of writing the argument to
typeof: with an expression or with a type. Here is an example with an expression:typeof (x[0](1))This assumes that
xis an array of pointers to functions; the type described is that of the values of the functions.Here is an example with a typename as the argument:
typeof (int *)Here the type described is that of pointers to
int.If you are writing a header file that must work when included in ISO C programs, write
__typeof__instead oftypeof. See Alternate Keywords.A
typeof-construct can be used anywhere a typedef name could be used. For example, you can use it in a declaration, in a cast, or inside ofsizeofortypeof.
typeofis often useful in conjunction with the statements-within-expressions feature. Here is how the two together can be used to define a safe “maximum” macro that operates on any arithmetic type and evaluates each of its arguments exactly once:#define max(a,b) ({ typeof (a) _a = (a); typeof (b) _b = (b); _a > _b ? _a : _b; })The reason for using names that start with underscores for the local variables is to avoid conflicts with variable names that occur within the expressions that are substituted for
aandb. Eventually we hope to design a new form of declaration syntax that allows you to declare variables whose scopes start only after their initializers; this will be a more reliable way to prevent such conflicts.Some more examples of the use of
typeof:
y with the type of what x points to.typeof (*x) y;
y as an array of such values.typeof (*x) y[4];
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];
To see the meaning of the declaration using typeof, and why it might be a useful way to write, rewrite it with these macros:
#define pointer(T) typeof(T *) #define array(T, N) typeof(T [N])
Now the declaration can be rewritten this way:
array (pointer (char), 4) y;
Thus, array (pointer (char), 4) is the type of arrays of 4 pointers to char.
Compatibility Note: In addition to typeof, GCC 2 supported a more limited extension which permitted one to write
typedef T = expr;
with the effect of declaring T to have the type of the expression expr. This extension does not work with GCC 3 (versions between 3.0 and 3.2 will crash; 3.2.1 and later give an error). Code which relies on it should be rewritten to use typeof:
typedef typeof(expr) T;
This will work with all versions of GCC.
聯(lián)系客服