How does dereferencing of a function pointer happen? How does dereferencing of a function pointer happen? c c

How does dereferencing of a function pointer happen?


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 us 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++.


C++03 §4.3/1:

An lvalue of function type T can be converted to an rvalue of type “pointer to T.” The result is a pointer to the function.

If you attempt an invalid operation on a function reference, such as the unary * operator, the first thing the language tries is a standard conversion. It's just like converting an int when adding it to a float. Using * on a function reference causes the language to take its pointer instead, which in your example, is square 1.

Another case where this applies is when assigning a function pointer.

void f() {    void (*recurse)() = f; // "f" is a reference; implicitly convert to ptr.    recurse(); // call operator is defined for pointers}

Note that this doesn't work the other way.

void f() {    void (&recurse)() = &f; // "&f" is a pointer; ERROR can't convert to ref.    recurse(); // OK - call operator is *separately* defined for references}

Function reference variables are nice because they (in theory, I've never tested) hint to the compiler that an indirect branch may be unnecessary, if initialized in an enclosing scope.

In C99, dereferencing a function pointer yields a function designator. §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 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’’.

This is more like Norman's answer, but notably C99 has no concept of rvalues.


Put yourself in the shoes of the compiler writer. A function pointer has a well defined meaning, it is a pointer to a blob of bytes that represent machine code.

What do you do when the programmer dereferences a function pointer? Do you take the first (or 8) bytes of the machine code and reinterpret that as a pointer? Odds are about 2 billion to one that this won't work. Do you declare UB? Plenty of that going around already. Or do you just ignore the attempt? You know the answer.