初识typeof

/*
 * min()/max() macros that also do
 * strict type-checking.. See the
 * "unnecessary" pointer comparison.
 */
#define min(x,y) ({ /
 const typeof(x) _x = (x); /
 const typeof(y) _y = (y); /
 (void) (&_x == &_y);  /
 _x < _y ? _x : _y; })

#define max(x,y) ({ /
 const typeof(x) _x = (x); /
 const typeof(y) _y = (y); /
 (void) (&_x == &_y);  /
 _x > _y ? _x : _y; })

 

这是在linux 内核代码kernel里看到的代码:实现较大和较小数的比较,好奇的是其中的typeof,搜索一下才知道:

 

typeof这个东西并不是ISO/IEC 9899:1999里的,也就是说不是标准C的运算符,这是gcc的一个扩展。在gcc的官方文档中单独列了一章来说这个东西(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 Section 5.39 [Alternate Keywords], page 239.

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, let’s 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.

 

 

<think> 我们正在处理的是表达式:typeof typeof 0 首先,我们需要计算最内层的 typeof 0 的结果。 根据引用[2]中的信息,typeof(0) 的结果是 "number"。 然后,我们要计算外层 typeof 的结果,即 typeof "number" 的结果。 因为 "number" 是一个字符串,所以 typeof "number" 应该返回 "string"。 因此,typeof typeof 0 的结果是 "string"。 验证: 第一步:typeof 0 → "number" (返回字符串) 第二步:typeof "number" → "string" (因为字符串的类型是string) 注意:typeof 操作符返回的是一个字符串,表示未经计算的操作数的类型。 所以最终答案是:"string" </think> ### 分析 `typeof typeof 0` 的结果 分步计算过程如下: 1. **最内层 `typeof 0`** 根据引用[2],数字类型的值使用 `typeof` 返回 `"number"`: $$ \textcolor{blue}{\text{typeof } 0} \rightarrow \text{"number"} $$ 2. **外层 `typeof "number"`** 字符串 `"number"` 作为操作数时: $$ \textcolor{green}{\text{typeof } (\text{"number"})} \rightarrow \text{"string"} $$ 原因:`typeof` 对 **字符串字面量** 始终返回 `"string"`(引用[2]表格)。 3. **最终结果** ```javascript typeof typeof 0 // 输出: "string" ``` ### 关键原理说明 1. **`typeof` 的运算顺序** `typeof` 是右结合运算符,从右向左计算(引用[1]): $$ \text{typeof}(\text{typeof}\ 0) = \text{typeof}(\text{"number"}) $$ 2. **类型返回值规则** | 操作数类型 | `typeof` 返回值 | 示例 | |------------------|-----------------|--------------------| | 数字(如 `0`) | `"number"` | `typeof 0` → `"number"` | | 字符串字面量 | `"string"` | `typeof "number"` → `"string"` | 3. **为什么不是 `"number"`?** 虽然内层 `typeof 0` 返回字符串 `"number"`,但外层 `typeof` 检测的是**该字符串本身的类型**(字符串类型),而非其字面含义。 ### 验证代码 ```javascript console.log(typeof typeof 0); // "string" ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值