If I want to define a pointer variable p to point to the function foo() defined as below, what should be the exact type of p?
int *foo(void *arg)
{
...
}
It should be
typedef int *(*funtion_foo_type)(void *);
You need to have the pointer as the pointer to a function, returning an int *, accepting a void* argument. You can make it like
int * (*p) (void *);
and then, you can use
p = foo;
Bearing in mind the comment of Kyrylo Polezhaiev, the type of p is
int*(*)(void*)
To declare p, you need to insert the name at the correct point in the type:
int*(*p)(void*);
but it is generally more readable to use an alias:
typedef int*(func_t)(void*);
func_t* p;
To make it more easy you could for the function declaration
int *foo(void *arg);
define an alias named as for example Tfoo that looks the same way as the function declaration itself
typedef int *Tfoo(void *);
After that to declare a function pointer to the function is very easy. Just write
Tfoo *foo_ptr = foo;
Otherwise you could write
typedef int * (* TFoo_ptr )(void *);
Tfoo_ptr foo_ptr = foo;
Or you could write a declaration of the function pointer directly without using the typedef/
int * (* foo_ptr )(void *) = foo;
Are you talking about pointer to function?
First define a pointer to function that takes void argumenta and return int
typedef int (*Ptrtofun)(void);
Now safely can point this to your function.
Ptrtofun p;
p = &foo(void);
Now you have a ptr p to function and can easily use it ..
Related
can you please explain in details this line of code inside struct:
There is a pointer to function but why would you reference it to struct?
void (*function)(struct Structure *);
what does this mean
(struct Structure *)?
(struct Structure *)
It means that the function have a struct Structure * argument. Actually it will make more sense with (struct Structure *variable of struct).
In this way, you can use a pointer to point a struct and should put the address of the struct variable which can be used in the function.
#include <stdio.h>
typedef struct circle{
int rad;
int area;
} Circle;
void ShowCircleInfo(Circle *info)
{
printf("rad value: %d\n", info->rad);
printf("area value: %d", info->area);
}
int main(void)
{
Circle circle_one;
circle_one.rad = 2;
circle_one.area = 3;
ShowCircleInfo(&circle_one);
return 0;
}
void (*function)(struct Structure *); declares function to be a pointer to a function that has a parameter of type struct Structure * and does not return a value.
For example
#include <stdio.h>
struct Structure {
int a;
void (*function)(struct Structure *);
};
void foo(struct Structure *a) {
if (a->function == NULL) a->function = foo;
a->a++;
printf("%d\n", a->a);
}
int main(void) {
struct Structure a = {42, foo};
struct Structure b = {0}; // don't call b.function just yet!!
a.function(&b); // foo(&b)
b.function(&a); // foo(&a)
}
See code running at https://ideone.com/7E74gb
In C, function pointer declarations have almost the same structure as function headers.
Only the function name will change to have some parantheses and a "*" in it, and the arguments won't have names, because only their types are important when using pointers (we don't access the values of the arguments, so we don't need their names).
They basically look like this:
<return_value> (*<function_name>)(<argument_list>)
So, for example, the function pointer for the function
void swap(int* a, int* b);
would be
void (*swap_ptr)(int*, int*);
Notice that the name of the pointer is in the place of the name of the function, and looks a bit odd compared to normal pointer declarations.
An excellent reading on this topic (you can skip the C++ stuff): https://www.cprogramming.com/tutorial/function-pointers.html
I know about typedef in C, but I got confused when I saw a declaration in the K&R book. The declaration is
typedef int (*PFI) (char *,char *)
What does it mean? What is PFI and how can we use it in our program?
Breaking it down, PFI is a pointer:
*PFI
To a function:
(*PFI)()
Which takes two arguments of type char *:
(*PFI)(char *, char *)
And returns an int:
int (*PFI)(char *, char *)
And declared as an alias of that type:
typedef int (*PFI)(char *, char *);
You could use it if you had a function that matches this pointer type, i.e:
int foo(char *x, char *y)
{
...
}
Then you can assign a pointer to the function to a variable of type PFI:
PFI f = &foo;
were you reading about pointer to functions?
If yes, then PFI is just a placeholder. It can be whatever name you give, it is just a function name. I guess it could mean "Preferred Function Interface" but that is just a guess.
so let's say you write a very crude code something like
typedef bool (*write_X_Bytes) (uint32 count, char *buffer);
then you can use it as a type in C since you used typedef in front of it like
write_X_Bytes print_line, print_word;
basically you give a prototype to user or whoever wants to use this code about parameters and return. You can checkout Linux kernel driver code for GPIO for real life usecase.
Basic rules of pointer declarations:
T *p; // p is a pointer to T
T *ap[N]; // ap is an N-element array of pointers to T
T *fp(); // fp is a function returning a pointer to T
T (*pa)[N]; // pa is a pointer to an array of T
T (*pf)(); // pf is a pointer to a function returning T
In both expressions and declarators, the subscript [] and function call () operators have higher precedence than the unary dereference * operator, so an expression or declarator like *f() is parsed as *(f()) - you are dereferencing the result of f. If you want to dereference f before calling it, you have to explicitly group the * operator with it - (*f)().
The way to read a hairy declaration is to start with the leftmost identifier and work your way out according to the rules above, applying them recursively to any function parameters.
If you have a function that uses abstract declarators in the parameter list like this one, just remember:
T * -> T *λ
T *[N] -> T *λ[N]
T (*)[N] -> T (*λ)[N]
T *() -> T *λ()
T (*)() -> T (*λ)()
where λ represents where the identifier would normally go.
So, the way to read this declaration is as
PFI -- PFI
typedef PFI -- is a typedef name for
typedef *PFI -- pointer to
typedef (*PFI) ( ) -- a function taking
typedef (*PFI) ( ) -- unnamed parameter
typedef (*PFI) ( * ) -- is a pointer to
typedef (*PFI) (char * ) -- char
typedef (*PFI) (char *, ) -- unnamed parameter
typedef (*PFI) (char *, *) -- is a pointer to
typedef (*PFI) (char *,char *) -- char
typedef int (*PFI) (char *,char *); -- returning int
In less formal terms, PFI is an alias for the type "pointer to a function taking two char * parameters and returning int".
So how would we use this?
A common use is declaring callbacks in function parameter lists:
void foo( char *foo, char *bar, PFI callback )
{
int x = callback( foo, bar );
...
}
That's a little easier to read than
void foo( char *foo, char *bar, int (*callback)(char *, char *) )
{
int x = callback( foo, bar );
...
}
It's also useful for declaring arrays or struct members:
int func1( char *x, char *y ) { ... }
int func2( char *a, char *b ) { ... }
...
struct s {
char *x;
char *y;
PFI f;
} blah = {"foo", "bar", func1};
PFI callbacks[] = { func1, func2, ... };
Again, that's a bit cleaner than writing
struct s {
char *x;
char *y;
int (*f)(char *, char *);
};
or
int (*callbacks[])(char *, char *) = { func1, func2, ... };
But...
"Being a bit cleaner" is not, by itself, sufficient reason to hide the type behind a typedef. You use a typedef to abstract away details about a type that the user of the type doesn't need to know about in order to use it.
For example, consider the FILE type in stdio.h. There is an entire API supporting the FILE type, such that you never need to know what it looks like under the hood.
In our case, however, we have to know that a PFI is a pointer to a function expecting two char * arguments and returning an int in order to use it. Using the typedef name saves a few keystrokes, but it also creates a "leaky" abstraction, since details about the type have to "leak" out to the programmer. In this case, it's honestly better to forego the typedef altogether and use the "naked" declaration.
https://cdecl.org/ says "declare PFI as pointer to function (pointer to char, pointer to char) returning int". That website didn't like the initial typedef but that makes it a type so you can you write:
PFI fp = f;
where f would have the prototype:
int f(char *, char *);
PFI just means "Pointer to a function returning int". It's a fast way to create a type that can be used quickly in code, because otherwise the syntax is complicated.
As one example, it's very useful for callback interfaces. You may want to define something like PFContext_t as a pointer to a function taking certain arguments and returning a context pointer. Then you can use the typedef in your data (if, for instance, you want to keep the pointer in a structure), and you can use the typedef in the arguments to a function called by the client, setting the callback.
I know that if I passed an argument like void (*func)(void *) to a variadic function, I can retrieve the argument like:
void (*func)(void *) = va_arg( args, void (*)(void) );
What if I pass something like void (** func)(void *)? What is the correct syntax to retrieve an argument of this type using va_arg?
Being frankly, your code is not standard-compliant. There is a tiny restriction for second argument of va_arg() macro:
... The parameter type shall be a type name specified such that the type
of a pointer to an object that has the specified type can be obtained
simply by postfixing a * to type. ...
According to this, notation like void (*)(void *) is unacceptable in this case. Since simple appending of * won't give you pointer to pointer to function. You may use only typedef-ed aliases:
typedef void (*func_ptr)(void *);
typedef void (**ptr_to_func_ptr)(void *);
func_ptr var1 = va_arg(ap, func_ptr);
ptr_to_func_ptr var2 = va_arg(ap, ptr_to_func_ptr);
Same as you've mentioned:
typedef void (** func_t)(void *);
func_t ppf;
va_list vl;
va_start(vl,n);
ppf = va_arg(vl, func_t);
...
To help pointer-to-function, I always use typedef as follows:
typedef void VoidFn(void *); // Function accepts void * and returns nothing.
That declares the prototype of the function as a typedef, allowing the use of the typedef elsewhere.
That way if you have this function:
void SomeFn(void *) {...}
you can declare this pointer:
VoidFn *fnPtr = &SomeFn; // A pointer to such a function.
This then makes it easier to change the prototype independently of the pointer, helping more... sophisticated constructs:
typedef void *VoidPtrFn(void *); // Function takes a void *, returning a void *
void *SomeOtherFn(void *) { ... }
VoidPtrFn *otherFnPtr = &SomeOtherFn;
VoidPtrFn **otherFnPtrPtr = &otherFnPtr;
I have two functions, each taking a pointer to a different type:
void processA(A *);
void processB(B *);
Is there a function pointer type that would be able to hold a pointer to either function without casting?
I tried to use
typedef void(*processor_t)(void*);
processor_t Ps[] = {processA, processB};
but it didn't work (compiler complains about incompatible pointer initialization).
Edit: Another part of code would iterate through the entries of Ps, without knowing the types. This code would be passing a char* as a parameter. Like this:
Ps[i](data_pointers[j]);
Edit: Thanks everyone. In the end, I will probably use something like this:
void processA(void*);
void processB(void*);
typedef void(*processor_t)(void*);
processor_t Ps[] = {processA, processB};
...
void processA(void *arg)
{
A *data = arg;
...
}
If you typedef void (*processor_t)(); then this will compile in C. This is because an empty argument list leaves the number and types of arguments to a function unspecified, so this typedef just defines a type which is "pointer to function returning void, taking an unspecified number of arguments of unspecified type."
Edit: Incidentally, you don't need the ampersands in front of the function names in the initializer list. In C, a function name in that context decays to a pointer to the function.
It works if you cast them
processor_t Ps[] = {(processor_t)processA, (processor_t)processB};
By the way, if your code is ridden with this type of things and switch's all over the place to figure out which function you need to call, you might want to take a look at object oriented programming. I personally don't like it much (especially C++...), but it does make a good job removing this kind of code with virtual inheritance.
This can be done without casts by using a union:
typedef struct A A;
typedef struct B B;
void processA(A *);
void processB(B *);
typedef union { void (*A)(A *); void (*B)(B *); } U;
U Ps[] = { {.A = processA}, {.B = processB} };
int main(void)
{
Ps[0].A(0); // 0 used for example; normally you would supply a pointer to an A.
Ps[1].B(0); // 0 used for example; normally you would supply a pointer to a B.
return 0;
}
You must call the function using the correct member name; this method only allows you to store one pointer or the other in each array element, not to perform weird function aliasing.
Another alternative is to use proxy functions that do have the type needed when calling with a parameter that is a pointer to char and that call the actual function with its proper type:
typedef struct A A;
typedef struct B B;
void processA(A *);
void processB(B *);
typedef void (*processor_t)();
void processAproxy(char *A) { processA(A); }
void processBproxy(char *B) { processB(B); }
processor_t Ps[] = { processAproxy, processBproxy };
int main(void)
{
char *a = (char *) address of some A object;
char *b = (char *) address of some B object;
Ps[0](a);
Ps[1](b);
return 0;
}
I used char * above since you stated you are using it, but I would generally prefer void *.
I started feeling comfortable with C and then I ran into type casting. If I have the following defined in an *.h file
struct data {
int value;
char *label;
};
and this in another *.h file
# define TYPE void*
How do I cast the void pointer to the struct so that I can use a variable "TYPE val" that's passed into functions? For example, if I want to utilize the value that TYPE val points to, how do I cast it so that I can pass that value to another functions?
(struct data*)pointer
will cast a pointer to void to a pointer to struct data.
Typecasting void pointer to a struct can be done in following
void *vptr;
typedef struct data
{
/* members */
} tdata;
for this we can typecast to struct
lets say u want to send this vptr as structure variable to some function
then
void function (tdata *);
main ()
{
/* here is your function which needs structure pointer
type casting void pointer to struct */
function((tdata *) vptr);
}
Note: we can typecast void pointer to any type, thats the main purpose of void pointers.