In the book, "Beginning C from Novice to Professional", the author does not use the address of operator when assigning a function to a function pointer. I typed in the code on my compiler both with and without the address of operator and it compiled and performed as expected both times. Why is this and which way would be preferred in an enterprise/business setting?
int sum(int, int);
int main(void)
{
...
int (*pfun)(int, int);
pfun = ∑
pfun = sum;
...
}
int sum(int x, int y)
{
return x + y;
}
This is a peculiarity of functions in C. The C standard says the following (C11 3.4.1p4):
I.e.
sumthat 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 allowsizeofor_Alignofbe 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 callpfunwithout dereferencing:pfun(1, 2); and insum(1, 2)sumis 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 aspfun = ∑.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,sumis 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
pfunbeing an object of function pointer type,&pfunwould actually get the address of the pointer variable, which is almost never what you wanted.