2

为什么在这里使用三个 * ?(glibc 源代码 glibc-2.9/sysdeps/mach/bits/libc-lock.h 第 81 行)

在线查看 libc-lock.h 代码 -> http://www.oschina.net/code/explore/glibc-2.9/sysdeps/mach/bits/libc-lock.h

/* Start a critical region with a cleanup function */
#define __libc_cleanup_region_start(DOIT, FCT, ARG)             \
{                                                               \
    typeof (***(FCT)) *__save_FCT = (DOIT) ? (FCT) : 0;         \
    typeof (ARG) __save_ARG = ARG;                              \
/* close brace is in __libc_cleanup_region_end below. */

/* End a critical region started with __libc_cleanup_region_start. */
#define __libc_cleanup_region_end(DOIT)                         \
if ((DOIT) && __save_FCT != 0)                                  \
   (*__save_FCT)(__save_ARG);                                   \
}

我不知道为什么在这里使用 3 *,为什么不

typeof (*(FCT)) * __save_FCT = (DOIT) ? (FCT) : 0;

提前致谢。

4

1 回答 1

1

我猜这是为了帮助确保它FCT是一个函数指针。当一个函数指针被取消引用时,它返回一个“函数指示符”。C99 6.5.3.2/4“地址和间接运算符”说:

一元 * 运算符表示间接。如果操作数指向一个函数,则结果是一个函数指示符

与数组名称非常相似,函数指示符的计算结果为函数指针,但在少数情况下除外。C99 6.3.2.1/4“左值、数组和函数指示符”:

函数指示符是具有函数类型的表达式。除非它是 sizeof 运算符或一元 & 运算符的操作数,否则类型为“函数返回类型”的函数指示符将转换为类型为“指向函数返回类型的指针”的表达式。

因此,您可以任意多次取消引用函数指针(或函数名称),但最终仍会得到“函数返回类型”的指示符。

FCT所以我认为如果宏参数使用了函数指针以外的东西,那么三重 deref 是为了让编译器抱怨。

于 2013-06-26T09:14:40.910 回答