So I was told that these are pretty much identical to each other
void function1 (void(func)(int), int arg){
func(arg);
}
void function2 (void(*func)(int), int arg){
func(arg);
}
When I execute this it throws no errors.
void print_plus_1(int p)
{
printf("p=%d\n", p 1);
}
void print_plus_2(int p)
{
printf("p=%d\n", p 2);
}
int main(void)
{
function1(print_plus_1, 1);
function2(print_plus_2, 1);
}
However when I initialize the same void (func) (int) vs void (*func) (int) pattern inside a struct
struct foo
{
void (func1)(int);
void (*func2)(int);
};
void print_plus_1(int p)
{
printf("p=%d\n", p 1);
}
void print_plus_2(int p)
{
printf("p=%d\n", p 2);
}
int main(void)
{
struct foo f;
f.func1 = print_plus_1;
f.func2 = print_plus_2;
return 0;
}
It throws a compiler error?
error: field 'func1' declared as a function
void (func1)(int);
Why does void (func)(void) work when written as a callback function but not as a field inside a struct?
CodePudding user response:
Nominally, void (func)(int)
declares a function that takes an int
and does not return anything, and void (*func)(int)
declares a pointer to such a function.
In standard base C, functions are not objects. They cannot be assigned to variables, passed as arguments, or stored in structure members.
However, C 2018 6.7.6.3 8 says:
A declaration of a parameter as “function returning type” shall be adjusted to “pointer to function returning type”, as in 6.3.2.1.
This means that, when you declare a parameter to be a function, it is automatically changed to be declare the parameter to be a pointer to a function. There is nothing in the C standard that says to do this adjustment when declaring a structure member. That is why you may nominally (but not actually) declare a function parameter to be a function but cannot declare a structure member to be a function.