I think I may be suffering from the dreaded \"accidental programmer\" disease, at least when it comes to typedefs and function pointers. So I\'ve been experimenting with all
It turns out that, in C/C++, both funcname
and &funcname
will yield the address of funcname
and can be assigned to a function pointer variable. This is actually just an oddity of how the syntax was designed for the language(s).
The thing about function pointers is that they're function pointers! :-) This is how you get your third sample to work:
#include <stdio.h>
typedef void (*print)(void);
// ^
void do_something (void) { printf("Hello World\n"); }
int main (void) {
print pr;
pr = do_something; // &do_something would also work.
pr();
return 0;
}
In terms of whether you use funcName
or &funcName
, it doesn't matter (in C at least). Section 6.3.2.1 Lvalues, arrays and function designators
states:
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".
The address of a function name and the plain function name both mean the same thing, so &
has no effect on a function name.
Similarly, when using function pointers, multiple dereferencing isn't a problem:
#include <stdio.h>
typedef void print(void);
static void dosomething(void) { printf("Hello World\n"); }
int main(void)
{
print *f1 = dosomething;
print *f2 = &dosomething;
f2();
(f1)();
(*f1)();
(**f2)();
(***f1)();
(****f2)();
(*****f1)();
}
That compiles cleanly under:
gcc -O3 -g -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes \
-Wold-style-definition -std=c99 xx.c -o xx
I would not claim that multiple stars is good style; it isn't. It is 'odd, and (yes, you may say it) perverse'. One is sufficient (and the one star is mainly for people like me who learned to program in C before the standard said "it is OK to call a function via a pointer without using the (*pointer_to_function)(arg1, arg2)
notation; you can just write pointer_to_function(arg1, arg2)
if you like"). Yes, it is weird. No, no other type (or class of types) exhibits the same behaviour, thank goodness.
Like C, C++ has pointer to functions: void (*)()
for example is a pointer to a function that takes no argument and returns no value. However, C++ has also introduced references to functions void (&)()
and there are implicit conversions between the two (though I don't remember the rules exactly).
Therefore:
funcname
is a reference to function&funcname
is a pointer to functionNote that taking the address (or a reference to) a function that is overloaded requires a static_cast
to the exact type (to resolve the overload).