I have an assignment to typedef function pointers which can point to main function. I tried something like this but I'm not sure if it's viable.
typedef mainPtr(*f[])(int, char**);
The thing that bothers me is that array size is not defined. How would you do this?
The type of main (in the form you want) is int main(int, char **).
A pointer to that is int (*main)(int, char **).
An array of those is int (*main[])(int, char **).
A typedef of that is typedef int (*mainPtr[])(int, char **);.
Whether you need a size for the array depends on how you will use the type. If you define and initialize an object of this type, its array size will be completed by counting the initializers. For example:
mainPtr p = { main, NULL };
will create an array with two elements.
In other uses, such as declaring a function parameter with this type, you may not need the array to be complete. An array function parameter is automatically adjusted to be a pointer, so the size is discarded anyway. However, if you wish, you could include the size in the typedef.
The syntax is easier if you typedef function itself:
typedef int mainfunc(int, char **);
Then you can use the "normal" pointer syntax:
/* definition of the function pointer*/
mainfunc *mainptr;
/* definitions of the function pointer arrays*/
mainfunc *mainptrarray[5];
mainfunc *mainptrarray1[] = {foo, bar, NULL};
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 am sure this question has been asked before. But I am wondering what does the typedef mean in this code:
typedef long (*HASH_CONS_HASH)(void *);
typedef bool (*HASH_CONS_EQUAL(void *, void *));
So far I understand:
HASH_CONS_HASH is a function that takes a void* and returns long
HASH_CONS_EQUAL is a function that takes two arguments of type void* and returns bool
But what does typedef mean here? is it necessary?
It declares the function pointer type.
now you can define HASH_CONS_HASH func1; where func1 is a pointer to the function returning long and not taking any parameters
or
HASH_CONS_EQUAL func2; where func2 is a pointer to function returning bool and taking two void pointer as parameters.
I'm fairly new to C, hence could someone please help me understand the below struct declaration?
extern struct server_module* module_open (const char* module_path);
Per my understanding, module_open is pointer to the struct server_module, however, didn't understand the last part of the statement i.e. (const char* module_path)
extern struct server_module* module_open (const char* module_path); declares module_open to be a function taking a parameter named module_path of type const char * and returning a struct server-module *.
module_open is a function which returns pointer to struct server_module
and const char* module_path is input argument type. Means function takes character string as an input
extern keyword is used to tell compiler that symbol is exist in different file
Does anyone know how to understand the fourth line of the code shown below?
typedef short Signal;
typedef struct Event Event;
typedef struct Fsm Fsm;
typedef void (*State)(Fsm *, Event const *);
It declares State as a typedef for void (*)(Fsm *, Event const *).
void (*)(Fsm *, Event const *) is a function pointer, pointing to a function that takes two arguments, Fsm * and Event const *, and returns void.
More information: How do function pointers in C work? and Typedef function pointer?
Let's go through the typedefs one by one:
The first line creates an alias for the type short. Now you can write Signal xyz = 0; and it would be equivalent to writing short xyz = 0;
The second and third lines let you write declarations of variables of the two struct types without the struct keyword. In other words, you can now write Fsm myFsm; instead of writing struct Fsm myFsm;
The last line declares a type State that corresponds to a void function pointer taking a pointer to Fsm and a pointer to Event.
The syntax may be a little tricky because of all the parentheses and the name being typedef-ed not being at the end of the declaration. You can tell it's a type definition for a function pointer, because the name of the type is in parentheses, and is prefixed with an asterisk. The rest of the typedef looks very much like a function signature, so the result is easy to read.