Search code examples
cfunction-pointersextern

Extern function pointer variable


One of libraries I use, requires setting an external function:

extern void* req_func(int param);

I have a function with this functionality, defined under another name in another c-file:

void* my_func(int param);

Why a function pointer variable to my_func crashes the program while running while a wrapper function does not?

void* my_func(intptr_t increment);                 // declaration
void* (*req_func)(int) = &my_func;                 // crash
void* req_func(int param) {return my_func(param);} // ok

Whether it is possible to create an alias of the existing function with a function pointer?


Solution

  • extern void* req_func(int param); declares a function named req_func. The library expects to be able to call this function. Calling the function will transfer program control to the instructions that make up the function.

    void* (*req_func)(int) = &my_func; defines a pointer named req_func. This pointer cannot be called. Attempting to call it as if it were a function will transfer program control to the bytes currently in the pointer. That can cause a crash in several ways. If the memory the pointer is in is not marked executable, the program will crash due to the hardware memory protection. If the processor does start executing the bytes of the pointer, they can be instructions that crash the program. Or they could be instructions that damage your program in other ways.

    While you can use a pointer to call a function, using req_func(param) in C source code, that works only if req_func is declared to be a pointer. If it is declared to be a pointer, the compiler knows that, when it sees req_func(param), it must get the value of the pointer and then use that value as the address to call. If req_func is declared to be a function, then the compiler translates req_func(param) differently: It uses the address of the function as the address to call.

    The declaration of any identifier must match its definition. Do not define a pointer in an attempt to match a declaration of a function.