Question

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.

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top