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.
Related
Suppose I have a main function as below:
void main()
{ int *p;
p = foo(31);
printf(ā%dā, (*p)+2);
bar(7); /* Body of function bar() not shown */
printf(ā%dā, (*p)+4);
}
int *foo(int x)
{
return &x;
}
Assuming the function bar() that compiles correctly, why the second result of the printf is 11 if the body of bar() does not write to its incoming arguments space.
More specifically, my question is why the incoming argument value of bar() which is 7 replaces the value 31?
What's more, when the main function pass the value 31 into foo(), how does the value 31 passed? By register? or the compiler creates a temporary variable to pass 31? And why the incoming argument of foo() and bar() share the same position in the memory
Function parameters are its local variables. So in this function definition
int *foo(int x)
{
return &x;
}
there is returned a pointer to a local variable.
As result the program has undefined behavior.
You can imagine the function definition and its call the following way
p = foo(31);
int *foo( /* int x */ )
{
int x = 31;
return &x;
}
The variable x will not be alive after exiting the function. Thus the pointer has an invalid value that is a value that does not point to an actual object. The memory allocated for the parameter of the function foo can be overwritten by a call of other function as for example by a call of the function printf..
Take into account that according to the C Standard the function main without parameters shall be declared like
int main( void )
and function foo should be declared before its usage. Otherwise the compiler can issue a message that either there is used incompatible types or it can not find the corresponding function.
The function foo receives a copy of the input parameter value in its local variable x. What foo sees does not depend on whether the argument to the function is constant or not.
The vatiable x is located on the stack and is freed when foo returns. So foo returns an address to a location in the stack. Returning a pointer to a local variable is an invitation for all kinds of problems.
In this case that same location most probably gets reused when bar is called.
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.
int main()
{
int a = 3;
func(&a)
}
(func being some arbitrary user defined function)
What is the meaning of this &? i know that its the reference variable, but so far I have only seen it being used in a function definition.
(Also, the variable a in the actual code is probably global or extern or something, I'm not sure :-/ ).
func being some arbitrary user defined function
It couldn't be "arbitrary" - it must take a pointer to int or a void* in order for the call to be legal.
This ampersand is the "take address" operator. It passes func the address of a, so that the func could, for example, modify it:
void func(int *pa) {
*pa = 4; // Note the asterisk - it "undoes" the effect of the ampersand
}
If your main prints a after the call to func, it prints 4 instead of 3.
Note that if you pass a instead of a pointer to a to a function that takes an int, not an int*, then modifications done to that int inside the function will have no effect on the parameter that you pass, because in C parameters are passed by value.
the variable a in the actual code is probably global or extern or something
It is probably not global, because there is no point in passing globals around: by virtue of being global, they are already accessible from everywhere.
the & means, that you are passing the address of that variable to the function.
That is needed when the function takes a pointer argument and you only have an atomic variable.
& is used in function call to pass the address of the variable (following &) to the function.
Since in C, there is no call by reference, you need to pass the address of the variable to the function if you are interested to reflect the changes to the variable in the caller.
The expression &<variable> yields the address of <variable>.
In your example it would allow func() to directly modify the value of main()'s local variable a, by dereferencing (e.g. *a = b).
In your example, the result might more simply and safely be returned from the function normally: a = func() for example), but the technique is more generally useful for:
Obtaining more than one result from a function through multiple pointer-arguments in addition to or instead of the return value.
Efficiently passing very large objects to functions (where the argument might be const qualified if it is for input only).
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 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.