Function pointers are often declared using typedef in C programs:
typedef int (*PFN_RETURNING_INT)(int, int);
The * indicates that this a pointer, to a function taking two int arguments and returning int.
I was digging around the Windows SDK header files and found this in rpcdec.h after running it through the C preprocessor:
typedef void __stdcall
RPC_INTERFACE_GROUP_IDLE_CALLBACK_FN (
RPC_INTERFACE_GROUP IfGroup,
void* IdleCallbackContext,
unsigned long IsGroupIdle
);
Note there is no * to indicate "pointerness". It seems to define a typedef to a function, not a pointer to a function. I was under the impression that functions are not first-class entities in the C type system, so I’m confused as how to understand the typedef.
When I define a function with a parameter of type RPC_INTERFACE_GROUP_IDLE_CALLBACK_FN, the MSVC compiler happily accepts it and appears to treat it like pointer to a function.
Is the typedef valid C? Should I be interpreting the typedef as defining a name to a pointer a function?
EDIT:
I tinkered some more with the following program:
#include <stdio.h>
typedef void (*PFN)(int x);
typedef void FN(int x);
void print(int x)
{
printf("%d\n", x);
}
void doit(FN fn)
{
fn(3);
}
void doit_p(PFN pfn)
{
pfn(3);
}
int main ()
{
doit(print);
doit_p(print);
// FN x = print; // Uncommenting these two lines fails to compile.
// doit(x);
exit(0);
}
Interestingly, the compiler happily accepts the program, but if I uncomment the two lines in main, it complains with "initialization of a function". It reminds me of the behaviour of array parameters in C, which "decay" to pointers. But is this bevaviour intentional, or accidental?
>Solution :
… I was under the impression that functions are not first-class entities in the C type system, so I’m confused as how to understand the typedef.
A typedef declares a name for a type. It does not declare a function or other entity, nor does it pass a function or otherwise use a function in an expression, so it does not matter whether a function is a first-class entity: The name simply identifies the type, and that does not require the type to be a first-class type.
When I define a function with a parameter of type…
A declaration of a parameter as a function is automatically adjusted to be a declaration of a pointer to a function. C 2018 6.7.6.3 8 says:
A declaration of a parameter as “function returning type” shall be adjusted to “pointer to function returning type”, as in 6.3.2.1.
Also, when a function designator is used in an expression other than as the operand of unary &, it is automatically converted to a pointer to the function, per C 2018 6.3.2.1 4:
A function designator is an expression that has function type. Except when it is the operand of the
sizeofoperator [which fails because applyingsizeofto a function is a constraint violation], 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”.