How does dereferencing of a function pointer happen?

Lazer picture Lazer · May 8, 2010 · Viewed 33.3k times · Source

Why and how does dereferencing a function pointer just "do nothing"?

This is what I am talking about:

#include<stdio.h>

void hello() { printf("hello"); }

int main(void) { 
    (*****hello)(); 
}

From a comment over here:

function pointers dereference just fine, but the resulting function designator will be immediately converted back to a function pointer


And from an answer here:

Dereferencing (in way you think) a function's pointer means: accessing a CODE memory as it would be a DATA memory.

Function pointer isn't suppose to be dereferenced in that way. Instead, it is called.

I would use a name "dereference" side by side with "call". It's OK.

Anyway: C is designed in such a way that both function name identifier as well as variable holding function's pointer mean the same: address to CODE memory. And it allows to jump to that memory by using call () syntax either on an identifier or variable.


How exactly does dereferencing of a function pointer work?

Answer

Norman Ramsey picture Norman Ramsey · May 8, 2010

It's not quite the right question. For C, at least, the right question is

What happens to a function value in an rvalue context?

(An rvalue context is anywhere a name or other reference appears where it should be used as a value, rather than a location—basically anywhere except on the left-hand side of an assignment. The name itself comes from the right-hand side of an assignment.)

OK, so what happens to a function value in an rvalue context? It is immediately and implicitly converted to a pointer to the original function value. If you dereference that pointer with *, you get the same function value back again, which is immediately and implicitly converted into a pointer. And you can do this as many times as you like.

Two similar experiments you can try:

  • What happens if you dereference a function pointer in an lvalue context—the left-hand side of an assignment. (The answer will be about what you expect, if you keep in mind that functions are immutable.)

  • An array value is also converted to a pointer in an lvalue context, but it is converted to a pointer to the element type, not to a pointer to the array. Dereferencing it will therefore give you an element, not an array, and the madness you show doesn't occur.

Hope this helps.

P.S. As to why a function value is implicitly converted to a pointer, the answer is that for those of use who use function pointers, it's a great convenience not to have to use &'s everywhere. There's a dual convenience as well: a function pointer in call position is automatically converted to a function value, so you don't have to write * to call through a function pointer.

P.P.S. Unlike C functions, C++ functions can be overloaded, and I'm not qualified to comment on how the semantics works in C++.