Почему в glibc libc-lock.h используется три *?

Почему здесь используется три *? (Исходный код 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;

Заранее спасибо.

1 ответ

Решение

Я предполагаю, что это поможет гарантировать, что FCT это указатель на функцию Когда указатель на функцию разыменовывается, он возвращает "указатель на функцию". C99 6.5.3.2/4 "Операторы адреса и косвенности" говорит:

Унарный оператор * обозначает косвенность. Если операнд указывает на функцию, результатом является обозначение функции

И так же, как и имена массивов, указатель функции оценивает указатель на функцию, за исключением нескольких случаев. C99 6.3.2.1/4 "Значения, массивы и функциональные обозначения":

Обозначение функции - это выражение с типом функции. За исключением случаев, когда это операнд оператора sizeof или унарный оператор &, указатель функции с типом "тип, возвращающий функцию" преобразуется в выражение, имеющее тип "указатель на тип, возвращающий функцию".

Следовательно, вы можете разыменовывать указатель на функцию (или имя функции) произвольное число раз, и в конце концов получить обозначение для "функции, возвращающего тип".

Так что я думаю, что тройной разыскивается, чтобы компилятор жаловался, если для FCT макро аргумент.

Другие вопросы по тегам