This question already has answers here:
How do function pointers in C work?
(12 answers)
Closed 9 years ago.
I'm learning C and I came to this expression:
void *(*routine)(void *)
I find it very confusing. Maybe it's a pointer...to a pointer... to a pointer?
If I wanted to pass this thing into a function, how would we manipulate it? I am trying to pass this routine construction as a parameter to a function that takes a void(*)(void)... but I am rather lost on what that actually means.
Start with the leftmost identifier and work your way out, remembering that absent explicit grouping with parentheses, [] and function call () bind before *, so
*a[N] is an N-element array of pointers
(*a)[N] is a pointer to an N-element array
*f() is a function returning a pointer
(*f)() is a pointer to a function
So,
routine -- routine
*routine -- is a pointer
(*routine)( ) -- to a function
(*routine)(void *) -- taking a single parameter of type void *
*(*routine)(void *) -- returning a pointer
void *(*routine)(void *) -- to void
void *(*routine)(void *);
declares a pointer to function that takes argument of type void * and returns pointer of type void *
Simple example:
#include <stdio.h>
void* foo(void* x) {
printf("Hello.");
}
int main(void) {
void *(*routine)(void *);
routine = foo; // assings foo to our function pointer
(*routine)(NULL); // invokes foo using this pointer
return 0;
}
outputs: Hello.
"If I wanted to pass this thing into a function" ~ here is example 2 for you:
#include <stdio.h>
void* foo(void* x) {
printf("Hello.");
}
typedef void *(*RoutinePtr)(void *); // alias to make your life easier
void routineInvoker(RoutinePtr routine) {
(*routine)(NULL); // invokes the routine
}
int main(void) {
RoutinePtr routine = foo; // creates a function pointer
routineInvoker(routine); // and passes it to our invoker
return 0;
}
Related
This question already has answers here:
How do function pointers in C work?
(12 answers)
Closed 9 years ago.
I'm learning C and I came to this expression:
void *(*routine)(void *)
I find it very confusing. Maybe it's a pointer...to a pointer... to a pointer?
If I wanted to pass this thing into a function, how would we manipulate it? I am trying to pass this routine construction as a parameter to a function that takes a void(*)(void)... but I am rather lost on what that actually means.
Start with the leftmost identifier and work your way out, remembering that absent explicit grouping with parentheses, [] and function call () bind before *, so
*a[N] is an N-element array of pointers
(*a)[N] is a pointer to an N-element array
*f() is a function returning a pointer
(*f)() is a pointer to a function
So,
routine -- routine
*routine -- is a pointer
(*routine)( ) -- to a function
(*routine)(void *) -- taking a single parameter of type void *
*(*routine)(void *) -- returning a pointer
void *(*routine)(void *) -- to void
void *(*routine)(void *);
declares a pointer to function that takes argument of type void * and returns pointer of type void *
Simple example:
#include <stdio.h>
void* foo(void* x) {
printf("Hello.");
}
int main(void) {
void *(*routine)(void *);
routine = foo; // assings foo to our function pointer
(*routine)(NULL); // invokes foo using this pointer
return 0;
}
outputs: Hello.
"If I wanted to pass this thing into a function" ~ here is example 2 for you:
#include <stdio.h>
void* foo(void* x) {
printf("Hello.");
}
typedef void *(*RoutinePtr)(void *); // alias to make your life easier
void routineInvoker(RoutinePtr routine) {
(*routine)(NULL); // invokes the routine
}
int main(void) {
RoutinePtr routine = foo; // creates a function pointer
routineInvoker(routine); // and passes it to our invoker
return 0;
}
I was reading this code on a website. I am fairly new to programming so please explain in a bit more detail.
#include <stdio.h>
// A normal function with an int parameter
// and void return type
void fun(int a)
{
printf("Value of a is %d\n", a);
}
int main()
{
// fun_ptr is a pointer to function fun()
void (*fun_ptr)(int) = &fun;
/* The above line is equivalent of following two
void (*fun_ptr)(int);
fun_ptr = &fun;
*/
// Invoking fun() using fun_ptr
(*fun_ptr)(10);
return 0;
}
Doubts-
I am not able to understand this type of declaration and assignment void (*fun_ptr)(int) = &fun;
I mean that if we declare a data type, then we do it like int a; and assign it as a=10; but here we are assigning it by writing (*fun_ptr)(10);. Kindly help.
Instead of this record
(*fun_ptr)(10);
you could just write
fun_ptr(10);
That is it is a function call of the function fun pointed to by the function pointer fun_ptr due to the initialization of that pointer in its declaration by the function address
void (*fun_ptr)(int) = &fun;
In turn this declaration could be written simpler like
void (*fun_ptr)(int) = fun;
because a function designator (in this case fun) used in expressions as for example an initializer is implicitly converted to pointer to the function.
You could use a typedef alias for the function type the following way
typedef void Func( int );
In this case the above declaration of the function pointer could look simpler like
Func *fun_ptr = fun;
Here is your program rewritten using a typedef for the function type of the function fun.
#include <stdio.h>
typedef void Func( int );
// Function declaration without its definition using the typedef
// This declaration is redundant and used only to demonstrate
// how a function can be declared using a typedef name
Func fun;
// Function definition. In this case you may not use the typedef name
void fun( int a )
{
printf("Value of a is %d\n", a);
}
int main(void)
{
// Declaration of a pointer to function
Func *fun_ptr = fun;
// Call of a function using a pointer to it
fun_ptr( 10 );
return 0;
}
Lets rewrite it a little bit, by using type-aliases and some comments:
// Define a type-alias names fun_pointer_type
// This type-alias is defined as a pointer (with the asterisk *) to a function,
// the function takes one int argument and returns no value (void)
typedef void (*fun_pointer_type)(int);
// Use the type-alias to define a variable, and initialize the variable
// This defines the variable fun_ptr being the type fun_pointer_type
// I.e. fun_ptr is a pointer to a function
// Initialize it to make it point to the function fun
fun_pointer_type fun_ptr = &fun;
// Now *call* the function using the function pointer
// First dereference the pointer, to get the function it points to
// Then call the function, passing the single argument 10
(*fun_ptr)(10);
Hopefully it makes things a little clearer what's going on.
Following is the meaning of two statments.
void (*fun_ptr)(int) = &fun; this is called declaring and initializing the fun_ptr in the same line , this is same as doing int a = 10;
(*fun_ptr)(10); is not assignment statement, it is invoking the function fun through function pointer fun_ptr.
you can also use typedef to create a new user defined out of function pointer and use as shown in above answer.
This is an advanced topic if you are new to programming, fun_ptr is a pointer to a function.
The declaration:
void (*fun_ptr)(int) = fun;
Means fun_ptr is a pointer to a function taking an int argument and returning void, initialize if with a pointer to the function fun. (you don't need the &)
The line:
(*fun_ptr)(10);
does not assign anything, it calls the function pointed to by fun_ptr, but is way to complex
fun_ptr(10);
As fun_ptr points to fun this is equivalant to `fun(10).
Using a function pointer has its use eg in a sort function where the comparison function is passed in as a function pointer so the sorting can be different between calls.
achieves the same thing and is much easier on the eyes.
1) I am currently trying to understand the following code, but I can't understand what void(*func)(void) means, I can understand that I am trying to save a the address of function named "function" from list0513, at void pointer func, but what does the casting (void) just before the equal sign mean?
// list0513.c
#include <dlfcn.h>
int main(void)
{
void *handle = dlopen("./list0513.so", RTLD_LAZY);
void (*func)(void) = dlsym(handle, "function");
(*func)();
dlclose (handle);
return 0;
}
According to the book, the function called "function" is called from the following script
// list0513dl.c
#include <stdio.h>
void function(void)
{
printf("Hello World\n");
}
2) but how do I make a list0513.so file? the only files I've made are .c files...
Thanks for reading this.
The declaration reads as follows:
func — func
*func — is a pointer to
(*func)( ) — a function taking
(*func)(void) — no parameters
void (*func)(void) — returning void
The func pointer is then initialized with the result of the dlsym call, which returns the address of the function ”function” in the library list0513.so.
General declaration rules for pointer types:
T *p; // p is a pointer to T
T *p[N]; // p is an array of pointer to T
T (*p)[N]; // p is a pointer to an array of T
T *f(); // f is a function returning a pointer to T
T (*f)(); // f is a pointer to a function returning T
In both declarations and expressions, the postfix [] subscript and () function call operators have higher precedence than unary *, so *f() is parsed as *(f()) (function returning pointer). To declare a pointer to an array or function, the * has to be explicitly grouped with the array or function declarator.
Declarations can get pretty complex - you can have an array of pointers to functions:
T (*a[N])(); // a is an array of pointers to functions returning T
or functions returning pointers to arrays:
T (*f())[N]; // f is a function returning a pointer to an array
or even pointers to arrays of pointers to functions returning pointers to arrays:
T (*(*(*a)[N])())[M];
You probably won’t see anything that hairy in the wild, though (unless you run across some old code of mine).
It is omitted a declare of function type. The full or expended version should like this:
// list0513.c
#include <dlfcn.h>
int main(void)
{
void *handle = dlopen("./list0513.so", RTLD_LAZY);
typedef void(*FUNC)();
FUNC func = dlsym(handle, "function");
func(); // call function
dlclose (handle);
return 0;
}
I'm having trouble understanding this specific declaration:
void (*signal(int, void (*fp)(int)))(int);
My previous understanding of function pointers was that the first item in brackets was the name of the function pointer.
eg
int (*MySuperDuperNameForASimpleAddFunction)(int, int);
I don't understand how it's possible to have anything other than identifiers in the first bracket.
void (*signal(int, void (*fp)(int)))(int);
signal is a function, taking :
an int
a function pointer taking an int and returning void
...and returning a function pointer taking an int and returning void. Phew.
Standard rule: find the leftmost identifier, then work your way out remembering that function-call () and [] bind before *, so *a[] is an array of pointers, (*a)[] is a pointer to an array, *f() is a function returning a pointer, and (*f)() is a pointer to a function. Apply this rule recursively for any function parameters.
With all that in mind, the declaration breaks down like so:
signal -- signal
signal( ) -- is a function taking
signal(int, ) -- an int parameter and
signal(int, fp ) -- a parameter named fp of type
signal(int, (*fp) ) -- pointer to
signal(int, (*fp)( )) -- function taking
signal(int, (*fp)(int)) -- an int parameter
signal(int, void (*fp)(int)) -- returning void
(*signal(int, void (*fp)(int))) -- returning a pointer to
(*signal(int, void (*fp)(int)))( ) -- a function taking
(*signal(int, void (*fp)(int)))(int) -- an int parameter
void (*signal(int, void (*fp)(int)))(int); -- returning void
So, signal takes two arguments, one of which is a pointer to a function taking an int and returning void, and returns a pointer to a function of the same type as fp.
The following was accepted by gcc:
static void (*signal(int, void (*fp)(int)))(int) ;
typedef void (sigfunc)(int) ;
static sigfunc* signal(int i, sigfunc* fp)
{
fp(i) ;
return fp ;
} ;
I have no idea why the return value from the signal function has to be wrapped around its definition in this way... and I suspect life is too short to allow me to discover !
I tried static void (*fp)(int) signal(int, void (*fp)(int)) but the computer said NO.
This question already has answers here:
What's the meaning of this piece of code? void (*signal(int sig, void (*func)(int)))(int);
(5 answers)
Closed 9 years ago.
I was studying signal handling in unix and came across this
void (*signal(int sig, void (*func)(int)))(int);
I dont understand this prototype and how this returns a pointer to a function.
I also read this answer:
How do function pointers in C work? but it's not clear to me.
It's supposed to return a function pointer but I dont understand where it specifies the return type as another function pointer.
The way I see it is that, if I use (*foo(int n)) in a function definition the return type of this function foo(int n) becomes a function pointer.Is this correct?
Is there a simpler example for this?
So, let's look at how a function pointer is declared.
return-type (*function-name)(parameter-list);
In the declaration you posted, there are two function-pointer types in play. The first is a parameter that's passed into a function that matches the signal prototype:
void (*signal(int sig, void (*func)(int)))(int);
// ^^^^^^^^^^^^^^^^^
Let's rename that function pointer type to handler and give it its own declaration.
typedef void (*handler)(int);
void (*signal(int sig, handler func))(int);
Now we can break down the rest of the declaration. The "inside" part is the actual function declaration:
...signal(int sig, handler func)...
And the "outside" describes the function pointer it returns:
void (...)(int);
This is also the same function-pointer type as our handler type, so with that typedef in place, we could redeclare the signal function like this:
handler signal(int sig, handler func);
(Much prettier.)
void (*signal(stuff))(int)
declares signal as returning a pointer to a function that takes an int as an argument and returns void. The stuff gives the arguments to signal, which in this case are
(int sig, void (*func)(int))
That is, the first argument to the function signal is an int, and the second argument is a function pointer taking an int as an argument and returning void.
Edit: Thus, if you made some call -- for example,
void foo (int x) {
return;
}
void *bar = (*signal)(0, &foo);
then bar will be a pointer to a function taking an int and returning nothing, and as such can be called as follows:
(*bar)(0);
We can use typedef to simplify the function pointer definition, which can help you to understand the long and complicated definition.
#include <stdio.h>
typedef void (*func)(int);
typedef void (*rtype)(int);
void myfunc(int a)
{
printf("A is %d\n", a);
}
// thus signal can be defined as this
// exactly the same as in your question
rtype signal(int a, func handler)
{
return myfunc;
}
int main()
{
signal(0, 0)(12);
return 0;
}
the above code should output: A is 12;
Hope helps!