This is a peculiarity of functions in C. The C standard says the following (C11 3.4.1p4):
- A function designator is an expression that has function type. Except when it is the operand of the
sizeof
operator, the _Alignof
operator, 65) 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''.
I.e. sum
that is a function designator is in any expression context, except when preceded by &
or the said 2 operators is converted to a pointer to function. Of course in the expression &sum
, the result is a pointer to a function. And ISO C does not allow sizeof
or _Alignof
be applied to a function, so in any expression that compiles, a function designator is either implicitly, or in the case of address-of operator, explicitly converted to a pointer to a function.
Even the function call operator ()
requires that its operand be a pointer to function, hence you can call pfun
without dereferencing: pfun(1, 2)
; and in sum(1, 2)
sum
is first converted to a pointer to a function, and then the function call operator is applied to this pointer.
There are coding conventions that say that a call through a function pointer should use the dereference operator *
, i.e. (*pfun)(1, 2)
, and likewise that the assignment be written as pfun = ∑
.
As such, writing (*pfun)(1, 2)
would not make it clearer that it is a pointer as the same syntax would equally work for a function designator, i.e. (*sum)(1, 2)
; in the latter, sum
is first converted to a pointer to a function since it is an operand to *
; then the dereference converts the pointer to function to a function designator again, and then since it is an operand to a function call operator, it is converted to a function pointer again.
Lastly, beware that pfun
being an object of function pointer type, &pfun
would actually get the address of the pointer variable, which is almost never what you wanted.