Is this forward declaration of a function pointer valid in C? Is this forward declaration of a function pointer valid in C? c c

Is this forward declaration of a function pointer valid in C?


C99:

6.2.7 Compatible type and composite type

clause 2:

All declarations that refer to the same object or function shall have compatible type; otherwise, the behavior is undefined.

6.7.5.1 Pointer declarators

clause 2:

For two pointer types to be compatible, both shall be identically qualified and both shall be pointers to compatible types.

Without further digging in the standard, it's easy to see that void and a function are not compatible types.

I'm willing to bet this doesn't change in C11. C has implicitly supported distinct code and data spaces and different sizes and representations of code and data pointers for a long time and it would be strange to remove this feature and confine the language to a smaller subset of machines to be available for. So, downvote with caution. Better with proof.


No, it is not valid, because essentially you are storing a regular pointer (NULL, void*) into a memory location which is actually a function pointer. You're just hiding that from the compiler, and the linker doesn't care, but at the end of the day you have undefined behavior, because the two pointer types are not necessarily compatible. Of course it may work on many systems, but perhaps not all.

For more on function pointers vs void pointers, see here: can void* be used to store function pointers? - while this is a slightly different case than what you're presenting, the answers are still relevant.


void * is an object type pointer which is different than function type pointer. They are not compatible types.

But:

Portabilitiy issues J.5.7. Function pointer casts

  1. A pointer to an object or to void may be cast to a pointer to a function, allowing data to be invoked as a function (6.5.4).

  2. A pointer to a function may be cast to a pointer to an object or to void, allowing a function to be inspected or modified (for example, by a debugger) (6.5.4).

Then why not fully hide the pointer in your module, and externalize functions to manipulate it? This will avoid the aliasing problem.