【问题标题】:Why is using three * in glibc libc-lock.h?为什么在 glibc libc-lock.h 中使用三个 *?
【发布时间】:2013-06-23 06:52:52
【问题描述】:

为什么在这里使用三个 * ? (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;

提前致谢。

【问题讨论】:

  • 因为它可能意味着不同的东西?
  • 它是否返回一个指向指针的指针?
  • 如果我在以单指针形式给出时没有错,那么在使用 __save_FCT 时可能会收到编译器警告。因为当FCT 是**** 类型时,__save_FCT 应该是单指针。否则当给定为(*(FCT)) 时,__save_FCT 将成为三重指针。 - 这是我的猜测。

标签: c gcc glibc typeof


【解决方案1】:

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

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

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

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

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

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

【讨论】:

  • 非常感谢 :) 如果是这样,应该是:typeof (***(FCT)) *__save_FCT = (DOIT) 吗? (**(FCT)) : 0 ; //2 在最后一个 FCT 之前 deref ??
  • 我在 11 年前在 cmets 中找到了检查 -> sourceware.org/git/… 'syntax so function and pointer-to-function arguments work right'
  • @zhao_x_g:很好的发现(我正在考虑尝试挖掘那组代码的“责备”,但决定我懒得尝试)。所以看起来改变利用了我所说的行为,但动机不同。
  • @zhao_x_g:关于 derefs 的数量 - 我认为一个就足够了 - 添加更多不应该改变行为(每次你 deref 一个函数 ptr 时,你得到的东西几乎是相同的函数点)。我不确定是否或为什么需要在 typeof 操作数中使用两个以上(甚至一个)deref 才能使函数名称与函数指针的行为相同。但这可能是因为我只是不完全了解这个小区域的 C 类型系统,或者可能是我并不真正了解 typeof 的工作原理 - 我从未直接使用过的非标准语言功能。
猜你喜欢
  • 2012-07-07
  • 2018-04-04
  • 2019-05-31
  • 2016-03-01
  • 2019-01-23
  • 2020-08-09
  • 2019-05-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多