typeof關(guān)鍵字是C語(yǔ)言中的一個(gè)新擴(kuò)展,。只要可以接受typedef名稱(chēng),,Sun Studio C 編譯器就可以接受帶有typeof的結(jié)構(gòu),包括以下語(yǔ)法類(lèi)別: - 聲明
- 函數(shù)聲明符中的參數(shù)類(lèi)型鏈表和返回類(lèi)型
- 類(lèi)型定義
- 類(lèi)型操作符s
- sizeof操作符
- 復(fù)合文字
- typeof實(shí)參
編譯器接受帶雙下劃線(xiàn)的關(guān)鍵字:__typeof和__typeof__,。本文中的例子并沒(méi)有遵循使用雙下劃線(xiàn)的慣例,。從語(yǔ)句構(gòu)成上看,typeof關(guān)鍵字后帶圓括號(hào),,其中包含類(lèi)型或表達(dá)式的名稱(chēng),。這類(lèi)似于sizeof關(guān)鍵字接受的操作數(shù)(與sizeof不同的是,位字段允許作為typeof實(shí)參,,并被解釋為相應(yīng)的整數(shù)類(lèi)型),。從語(yǔ)義上看,typeof 關(guān)鍵字將用做類(lèi)型名(typedef名稱(chēng))并指定類(lèi)型,。 使用typeof的聲明示例下面是兩個(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 */ 以下示例用于聲明指針和數(shù)組,。為了進(jìn)行對(duì)比,,還給出了不帶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用于表達(dá)式,,則該表達(dá)式不會(huì)執(zhí)行,。只會(huì)得到該表達(dá)式的類(lèi)型。以下示例聲明了int類(lèi)型的var變量,,因?yàn)楸磉_(dá)式foo()是int類(lèi)型的,。由于表達(dá)式不會(huì)被執(zhí)行,所以不會(huì)調(diào)用foo函數(shù),。 extern int foo(); typeof(foo()) var; 使用typeof的聲明限制請(qǐng)注意,,typeof構(gòu)造中的類(lèi)型名不能包含存儲(chǔ)類(lèi)說(shuō)明符,如extern或static,。不過(guò)允許包含類(lèi)型限定符,,如const或volatile。例如,,下列代碼是無(wú)效的,,因?yàn)樗?tt>typeof構(gòu)造中聲明了extern: typeof(extern int) a; 下列代碼使用外部鏈接來(lái)聲明標(biāo)識(shí)符b是有效的,表示一個(gè)int類(lèi)型的對(duì)象,。下一個(gè)聲明也是有效的,,它聲明了一個(gè)使用const限定符的char類(lèi)型指針,表示指針p不能被修改,。 extern typeof(int) b; typeof(char * const) p = "a"; 在宏聲明中使用typeoftypeof構(gòu)造的主要應(yīng)用是用在宏定義中,。可以使用typeof關(guān)鍵字來(lái)引用宏參數(shù)的類(lèi)型。因此,,在沒(méi)有將類(lèi)型名明確指定為宏實(shí)參的情況下,,構(gòu)造帶有所需類(lèi)型的對(duì)象是可能的。
另外一篇: 另一種引用一個(gè)表達(dá)式類(lèi)型的方法就是使用typeof,,使用這個(gè)關(guān)鍵字的語(yǔ)法看上去有點(diǎn)像使用sizeof,,但從本質(zhì)上講,它更像是使用typedef定義一個(gè)類(lèi)型名稱(chēng),。 可以使用表達(dá)式或是一個(gè)類(lèi)型名來(lái)引用類(lèi)型,。比如下面是一個(gè)使用表達(dá)式的例子: typeof (x[0](1)) 這里假設(shè)x是一個(gè)指向多個(gè)函數(shù)的指針數(shù)組。這里得到的類(lèi)型實(shí)際是函數(shù)值的類(lèi)型,。 下面是一個(gè)使用類(lèi)型名的例子: typeof (int *) 這里得到的類(lèi)型是指向int型的指針 如果你要把typeof寫(xiě)在頭文件中,,而且這些頭文件是要用在ISO C程序中,那么應(yīng)該寫(xiě)成__typeof__而不是typeof typeof能被用在任何需要引用類(lèi)型名的情況下,,比如你可以用在聲明,、顯示類(lèi)型轉(zhuǎn)換(cast)或是在sizeof和typeof內(nèi)使用。 typeof在協(xié)助內(nèi)嵌表達(dá)式的聲明時(shí)非常有用,。這里演示一個(gè)如何定義一個(gè)安全(在任何情況下,,各參數(shù)只會(huì)被計(jì)算一次)的求最大值的宏。 #define max(a,b) ({ typeof (a) _a = (a); typeof (b) _b = (b); _a > _b ? _a : _b; }) 讓局部變量名以下劃線(xiàn)開(kāi)關(guān)的原因是避免與內(nèi)嵌表達(dá)式被使用時(shí)傳進(jìn)來(lái)的參數(shù)名相沖突,。我們更希望建立一種新的語(yǔ)法規(guī)則,,按照這種語(yǔ)法規(guī)則,聲明的變量的作用域只在該變量初始化之后,。相信這會(huì)是一種更加可靠的避免沖突的方法,。 一些別的使用typeof的例子: 1、y的類(lèi)型與x所指向的類(lèi)型相同 typeof (*x) y; 2,、 y的類(lèi)型是指向字符的指針數(shù)組 typeof ( typeof (char *) [4]) y; 這與傳統(tǒng)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)型的指針數(shù)組。 關(guān)于兼容性:在GCC 2中提供了一個(gè)更加局限的擴(kuò)展,,這個(gè)擴(kuò)展允許用戶(hù)使用typedef T = expr;以使T類(lèi)型與expr類(lèi)型相同,。這個(gè)擴(kuò)展在GCC3.0和3.2版本中會(huì)出現(xiàn)問(wèn)題,在3.2.1及以后的版本中會(huì)報(bào)錯(cuò),。不過(guò)可以用下面的方法來(lái)重寫(xiě): typedef typeof(expr) T; 這種方法寫(xiě)的代碼在所有GCC版本中都可行,。 原文: http://gcc./onlinedocs/gcc-4.3.3/gcc/Typeof.html#Typeof
5.6 Referring to a Type with typeof Another way to refer to the type of an expression is with typeof . The syntax of using of this keyword looks like sizeof , but the construct acts semantically like a type name defined with typedef . 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 x is 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 of typeof . 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 of sizeof or typeof . typeof is 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 a and b . 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 :
- This declares
y with the type of what x points to. 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];
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.
|