I'm trying to understand a code which have the following lines:
void terminate_pipe(int);
code code code...
struct sigaction new_Sigiterm;
new_Sigiterm.sa_handler = terminate_pipe;
My question are:
What is the meaning of calling a function like this? Is it going to
just put NULL as the parameter?
It is void, so new_Sigiterm.sa_handler will be NULL no matter what?
thanks.
new_Sigiterm.sa_handler is most likely a pointer that points to a function. By running
new_Sigiterm.sa_handler = terminate_pipe;
It's similar to saying
new_Sigiterm.sa_handler = &terminate_pipe;
(Like in pointers). This is not running the function, it's just making a pointer that points to the function, if you "run" the pointer, the pointed function will run.
This is how to declare function pointer:
void function(int x);
int main()
{
//Pointer to function
void (*foo) (int);
//Point it to our function
foo = function;
//Run our pointed function
foo(5);
}
More info about function pointers
Code like this assignment is setting a handler (sometimes called a function pointer): Basically, the address of the function to run, at a given time.
The syntax for this in C is to name the function, but don't put () on the end. That returns the address of the function.
new_Sigiterm.sa_handler = terminate_pipe;
void terminate_pipe(int); is not calling of function it is Forward declaration of function.
In new_Sigiterm.sa_handler sa_handler is a Function Pointer.
Related
I am looking at some late 80's C code. I have the following definition.
void (*_flush())(){ /* body ommitted */ }
I believe this is a function, _flush , with void as its argument list and returns a function pointer that returns void and has void as its argument list.
The equivalent in two parts:
typedef void (*funcptr)(void);
functptr flush(void){ /* body ommitted */ }
Do I understand the old notation correctly?
Yes, your understanding is (almost) correct:
cdecl> explain void (*_flush())()
declare _flush as function returning pointer to function returning void
It's not correct to say that your function has void as its argument list, though. A function like:
void func()
Doesn't take no arguments, it takes an unspecified number of arguments. You could call it in whichever of these ways is appropriate:
func()
func(a);
func(a, b, c);
and so on. If the implementation of _flush doesn't make use of any parameters, you can probably safely use void as you suggest, but your example doesn't include enough information to say.
A good reference: C function with no parameters behavior
Use http://www.cdecl.org/ to get an nice translation of your function.
void (*_flush())()
declare _flush as function returning pointer to function returning void
Had the definition of function _flush() used any parameters itself, they would have been listed between the last ) and { so we can be confident that the function _flush takes no arguments.
void (*_flush())() { /* body omitted */ }
//----------------^
The return value of flush is itself a function, let's call it foo
void foo(...)
declare foo as function returning void
Here it is known that the function returns void, but its parameter list could be of any number of parameters and of any number of any type. Just not known from the info given but likely discernible from the body of _flush.
While I went through some code, I found this declaration.
typedef int (*tMeshTable)(tOutPar *);
What is its intended purpose?
tMeshtable typedef'd to be a pointer to a function taking an tOutPar pointer and returning an int.
It's easier to say tMeshTable than that whole thing every time.
So when you want to pass it around to a function, for instance:
void functionThatCallsFunction(tMeshTable myFunction) {
tOutPar * outPar;
/* This next line calls the function that was passed into this function as a parameter */
int result = (*myFunction)(outPar);
}
it looks a lot cleaner than the raw function pointer syntax.
This page talks all about function pointers. You should give it a look: http://www.newty.de/fpt/fpt.html
Can anyone please tell me,
what exactly is meant by registering a callback function in C (with some examples)?
what are Notify callbacks ?
what are Asynchronous call backs?
Registering a callback function simply means that you are arranging for an external entity to call your function.
It might happen at a later time, or it might happen straight away. A straightforward example is qsort. It is declared like this:
void qsort(void *base, size_t nel, size_t width,
int (*compar)(const void *, const void *));
In order to use it, you must pass a pointer to a function that compares elements - the callback.
That was a simple example but generally "registering a callback" means passing a function pointer to someone who will call it for you in the future.
Registering a callback means to pass a function pointer to the one who will call your function through the pointer
For easier understanding Consider A and B who are two entities involved in the code.
A has written a function say myFunc
char myFunc(int a)
{
/* Code written by A*/
}
Now when it is said A will register a callback with B, it means A will send the function pointer to B
By sending function pointer to B, A provides an access to the function
To register the callback there will be a function where A can pass the pointer
A will call the function as
cb_register(myFunc);
// Passed the address of Function
This cb_register function is defined in B as
typedef void (*cb_fn_ptr)(int a);
void cb_register(cb_fn_ptr cb)
{
// In this function B can store the address in a structure member
}
For example a struct_B is declared which stores
struct s_B {
cb_fn_ptr cb;
// cb will have address whenever B
};
B has stored the address (which the function pointer points to) and can use it to call the function later.
When B calls the function through the function pointer it is called as callback.
B just needs to know the prototype of the function to call the function and can be completely unaware of what the function does.
In this case function will call as
struct s_B temp;
char ret_val;
int arg_val;
ret_val = temp->cb(arg_val)
//This is a callback
I have a function with definition :
int foobar(char *ptr,...)
the function call is as follows :
int (*fooptr) (char *,...) = foobar;
I am not able to understand how is the function getting called ...
Thanks in advance
That's not a function call.
It is declaring a function pointer variable called fooptr that holds the address of the function.
To call that function via the pointer you would do e.g.:
int return_value = (*fooptr)(char_ptr, x, y, z);
It's not a call. It is a declaration of fooptr.
The function is not getting called with the code you have posted. The first line is the function declaration, the second is creating a pointer to it. To call it you have to use foobar(myCharPtr[, other arguments]) or fooptr(myCharPtr[, other arguments]).
The function is not getting called in your example. Its address is stored in the fooptr variable, which is a function pointer. If you later call that function pointer while it's still pointing to foobar function, it'll call foobar function.
You can write the second line as:
// declare fooptr as a variable of type function pointer
// taking (char*,...) and returning int
int (*fooptr) (char *,...);
// take the address of foobar function and assign it to fooptr
fooptr = &foobar;
to make it clearer.
This is a varargs function, which can receive a variable number of parameters (similar to printf). the second line you give is an assignment, not a function call.
I came across this in embedded hardware using C.
#define EnterPWDN(clkcon) ( (void (*)(int))0xc0080e0 ) (clkcon)
I have no idea how is this function macro working. I understand clkcon is the function parameter to EnterPWDN, but what is happening after that?
It casts the address 0xc0080e0 to a pointer to function taking an int and returning void, and calls that function, passing clkcon as the parameter.
Spelled out:
typedef void (func_ptr*)(int);
func_ptr func = (func_ptr)0xc0080e0;
func(clkcon);
(If you haven't come across function pointers, you might want to grab a good C introduction and read up on the subject.)
Its a void function pointer that takes an int as a parameter. The function is held at the specific memory address 0xc0080e0.
(void (*)(int))
The above is a function pointer declaration. First comes the void return type. Next comes the fact that its a pointer and finally the int tells you what the parameter to the function is. The memory address is the location the function is stored at and the whole thing is casting that memory address into the correct function pointer type and then calling the function and passing "clkcon" to it.
Excellent answers Goz and sbi, but to put it another way:
At a specific address (0xc0080e0) in memory, possibly in a ROM, there is a function. You call this function with the int clkcon argument.