Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Is `typedef` of a function standard C syntax, and how does it differ from a `typedef` of a function pointer?

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:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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 sizeof operator [which fails because applying sizeof to 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”.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading