Reputation: 682
Say that I have a pointer to function theFunc
. theFunc
takes along a pointer that points to the address where theFunc
is stored . Is this possible?
Using it would look like this:
funcPtr(funcPtr);
That calls the function pointed to by funcPtr, and then passes along the address of the pointer. I do not want to use void pointers because I want to change the function pointed to by funcPtr
.
Upvotes: 2
Views: 591
Reputation: 213809
theFunc
takes along a pointer that points to the address wheretheFunc
is stored . Is this possible?
Yes it is possible but it's also 100% pointless. It is similar to addressing a letter to yourself, writing down your postal address in the letter. The you go to place that letter in your own mailbox while you are already present at that physical address stated in the letter. It doesn't make any sense - you already know the address since you are already there, so why write the letter in the first place? Rule #1 in program design: don't do really strange things just because you can.
Any function name in C may decay to a function pointer when used in an expression. Thus:
void theFunc (void)
{
uintptr_t address = (uintptr_t)theFunc;
}
There is no need for any parameters.
Upvotes: 1
Reputation: 14127
Yes. It is possible. C supports incomplete function types in a form of functions declared with no prototypes. For example:
int fun();
Declares a function that takes an unspecified number of arguments and returns int
. This allows to define a cascade of function types that approach the desired function type that takes a pointer to itself as a first argument. The desired type reached at infinity but 2-3 levels are enough for practical type safety.
For example, code below compiles without a warning even in pedantic mode.
int foo(int(int()));
int main(void) {
int (*fptr)(int(int())) = foo;
return fptr(fptr);
}
See https://godbolt.org/z/1s1bGMd9P
Upvotes: 2
Reputation: 28084
You cannot simply typedef a function type that accepts itself as a parameter. I.e. something like this will not work:
/* Will cause a compilation error, MyFuncType used a parameter is not yet defined: */
typedef void(*MyFuncType)(MyFuncType);
However - you can still use a void*
to achieve what you want.
The typedef is using void*
, but inside the function you can cast it to your function pointer type, modify it and call it.
See here:
typedef void(*MyFuncType)(void*);
void f(void* pF)
{
if (pF)
{
MyFuncType ff = (MyFuncType)pF;
/* Change ff here if you need. */
/* Call it: */
ff(0);
}
}
int main()
{
f(f);
return 0;
}
Update:
Following the comment from @JosephSible-ReinstateMonica below, I added a 2nd solution. It does not involve a cast between data and function pointers, but it requires another typedef
and a cast when calling f
with itself:
typedef void(*FuncType1)(void);
typedef void(*MyFuncType)(FuncType1);
void f(MyFuncType pF)
{
if (pF)
{
/* Change pF here if you need. */
/* Call it: */
pF(0);
}
}
int main()
{
f((MyFuncType)f);
return 0;
}
Upvotes: 4