& operator optional in function pointer assignment
In the following code:
/* mylog.c */
#include <stdio.h>
#include <stdlib.h> /* for atoi(3) */
int mylog10(int n)
{
int log = 0;
while (n > 0)
{
log++;
n /= 10;
}
return log;
}
int mylog2(int n)
{
int log = 0;
while (n > 0)
{
log++;
n >>= 1;
}
return log;
}
int main(int argc, const char* argv[])
{
int (*logfunc)(int); /* function pointer */
int n = 0, log;
if (argc > 1)
{
n = atoi(argv[1]);
}
logfunc = &mylog10; /* is unary '&' operator needed? */
log = logfunc(n);
printf("%d\n", log);
return 0;
}
in the line
logfunc = &mylog10;
I've noticed that the unary &
(address of) operator is optional, and the program compiles and runs the same way either with or without it (in Linux with GCC 4.2.4). Why? Is this a compiler-specific issue, or perhaps two different language standards being accepted by the compiler? Thanks.
You are correct that the &
is optional. Functions, like arrays, can be automatically converted into pointers. It's neither compiler-specific nor the result of different language standards. From the standard, Section 6.3.2.1, paragraph 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".
Operator &
is indeed optional when taking the address of a function in your context (assigning it to something). It is not compiler-specific, it follows from the formal definition of the language.
Symmetrically, operator *
is optional when invoking the function through a pointer. In your example, you could invoke the function as either (*logfunc)(n)
or logfunc(n)
. You used the latter, but the former would work as well.
Answering in C++. For C the same holds
Quote from the C++ standard (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.50)
The same for arrays. (4.2.1)
An lvalue or rvalue of type “array ofN T” or “array of unknown bound of T” can be converted to an rvalue of type “pointer to T.” The result is a pointer to the first element of the array.
But please DO note that these are conversions and by no means is a function a function-pointer or is an array a pointer. HTH
From the standard (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’’.
So yes, omitting the &
yields a pointer to function anyway.