Why is using three * here ? (glibc source code glibc-2.9/sysdeps/mach/bits/libc-lock.h line 81)
online view libc-lock.h code -> 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); \
}
I don't know why use 3 * here, why not
typeof (*(FCT)) * __save_FCT = (DOIT) ? (FCT) : 0;
Thanks in advance.
I'd guess that it's to help ensure that FCT
is a function pointer. When a function pointer is dereferenced, it returns a "function designator". C99 6.5.3.2/4 "Address and indirection operators" says:
The unary * operator denotes indirection. If the operand points to a function, the result is a function designator
And much like array names, a function designator evaluates to a function pointer except in a a couple cases. C99 6.3.2.1/4 "Lvalues, arrays, and function designators":
A function designator is an expression that has function type. Except when it is the operand of the sizeof operator or the unary & operator, a function designator with type "function returning type" is converted to an expression that has type "pointer to function returning type".
Therefore you can dereference a function pointer (or function name) an arbitrary number of times and still end up with a designator for a "function returning type".
So I think that the triple deref is there to get the compiler to complain if something other than a function pointer is used for the FCT
macro argument.