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