Reputation: 326
I have the following code:
typedef void (*func_type)(int a, int b);
func_type func;
int main()
{
func = (func_type)GetProcAddress(NULL, "func");
}
This code works fine, but I would like to change func_type func;
to void func(int a, int b);
(because code completion shows "func_type" instead of "func" when typing the parameters).
But when I try to change this, the compiler tells me that in the main function "expression must be a modifiable lvalue". I tried to look online but did not find an answer to my problem.
Code becomes this:
typedef void (*func_type)(int a, int b);
void func(int a, int b);
int main()
{
func = (func_type)GetProcAddress(NULL, "func");
}
Upvotes: 2
Views: 167
Reputation: 14107
Functions in C behave similar to arrays. They both decay to pointers. Whenever function name is used it automatically decays to a pointer to this function. The exceptions are &
and sizeof
operators. Operator sizeof
does not accept a function as operand. That is why foo
and &foo
are equivalent.
Functions itself are non-modifiable by design. Any attempt of modifying it i.e. by memcpy
-ing to a function pointer is undefined behaviour.
Surprisingly, function call operator ()
does not take a function as operand but a pointer to a function.
Therefore, a function call
foo(1);
is actually
(&foo)(1);
Because foo
decays to &foo
before evaluation of the function call.
That is why one can interchangeably use functions and function pointer in function call operands.
void foo(int) { ... }
void (*bar)(int);
foo(1); // foo decays to &foo which is a function pointer
bar(2); // bar is already a function pointer
To solve the original problem I suggest keeping func
be a function pointer, that initially points to some dedicated function but it can be overwritten later on:
typedef void func_type(int,int);
void default_func(int a, int b) { ... }
funt_type* func = default_func; // decays to &default_func !
int main()
{
func(1,2); // calls default_func
func = (func_type*)GetProcAddress(NULL, "func");
func(3,4); // calls func from dll/so
}
I've decided to use function types (not function pointer types) what is a bit un-orthodox. IMO, it make syntax more visually pleasing, and it is easier to parse by a human. Moreover, it is explicit about what is a pointer what is not.
Upvotes: 1
Reputation: 222372
typedef void (*func_type)(int a, int b);
declares func_type
to be a type that is a pointer to a function. Then func_type func;
declares func
to be a pointer. Your proposed alternative, void func(int a, int b);
declares func
to be a function.
Since you can assign to a pointer, func = …;
works with the first declaration. Since you cannot assign to a function, func = …;
does not work with the second declaration.
To declare func
to be a pointer to a function without using a typedef
, use void (*func)(int, int);
.
Upvotes: 1