Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I am trying to find out if the following forward declaration is valid in ANSI-C:

First file:

extern void * fptr;   // opaque forward declaration.
int main (void) {
  fptr = NULL;        // set the function pointer to NULL
}

Second file:

typedef int (*fptr_t)(int);
fptr_t fptr;         // real declaration of the function pointer

To me, this should be invalid since fptr if declared with two different types, but neither gcc nor clang gives any warning.

I would be more specifically interested in precise points of the C11 standard that allow to conclude why it is valid (or invalid).


EDIT: in the C11 standard,6.2.7:2 says:

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

But I cannot find how to decide if void* is compatible with fptr_t.

like image 515
Anne Avatar asked Apr 21 '16 06:04

Anne


People also ask

Does C support forward declaration?

Classes. In some object-oriented languages like C++ and Objective-C, it is sometimes necessary to forward-declare classes. This is done in situations when it is necessary to know that the name of the class is a type, but where it is unnecessary to know the structure.

Can you forward declare a function?

To write a forward declaration for a function, we use a declaration statement called a function prototype. The function prototype consists of the function header (the function's return type, name, and parameter types), terminated with a semicolon. The function body is not included in the prototype.

How a pointer to a function is declared in C?

Master C and Embedded C Programming- Learn as you go A pointer is a variable whose value is the address of another variable or memory block, i.e., direct address of the memory location. Like any variable or constant, you must declare a pointer before using it to store any variable or block address.

Can we use pointer with function in C?

In C, like normal data pointers (int *, char *, etc), we can have pointers to functions. Following is a simple example that shows declaration and function call using function pointer.


2 Answers

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.

like image 177
Alexey Frunze Avatar answered Sep 28 '22 11:09

Alexey Frunze


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.

like image 45
John Zwinck Avatar answered Sep 28 '22 09:09

John Zwinck