typedef int (*P)(char *(*)());
int (*P)(char *(*)());
Both seems to be doing the same thing to me,what's the typedef there for?
The first declares a type called P that you can use in the declaration of other variables. The second declares a variable of that same type.
For illustrative purposes:
typedef int (*P)(char *(*)());
int main() {
int (*Q)(char *(*)());
P R;
}
In this example the variables Q and R have exactly the same type.
The typedef defines P to be a function pointer type. The second version defines P to be a function pointer.
A type can be used to declare variables. After
typedef int (*P)(char *(*)());
you can use
P p;
which will be equivalent to
int (*p)(char *(*)());
The simple answer would be you are creating a new datatype through typedef.
Let's take a simple example, in embedded system we use only unsigned numbers.
Now 1 way is I write
unsigned int xyz;
So here I would have to type unsigned everywhere.. What if I forget to type unsigned somewhere, it's very difficult to figure out that if the code is released. So simple way would be
typedef unsigned int uint;
So now you can use uint as a datatype. So whenever parser encounter uint, it would read it as unsigned int.
So in your case you can use P as a datatype in code. So Like in the first example
P xyz ;
would be parsed as
int (*xyz)(char *(*)());
Related
typedef int (*t_built)(t_cmds *, t_table *);
struct cmdline
{
char * reserved[7]; /* "echo pwd cd unset export exit env" */
t_built builtin[7];
}
How can I store my builtin functions into builtin array with same indexes as in reserved array. Can you help me to understand how this syntax works and for what declared typedef for function pointer.
Let's decompose the declarations:
int f(int);
declares f as a function taking an int and returning an int.
This can be written with parentheses (this is useless here but harmless):
int (f)(int);
The following declaration:
int *f(int);
declares f as a function taking an int and returning a pointer to an int.
This time, parentheses change the order of evaluation:
int (*f)(int);
declares f as a pointer to a function taking an int and returning an int.
typedef is used to define a type instead of a variable.
Finally the sequence:
typedef int (*f)(int);
f a[7];
declares a as an array of seven elements of type f, f describing a pointer to a function taking an int and returning an int.
By the way, there is a converter for that sort of things: cdecl: C gibberish ↔ English.
I have a sample code for a microcontroller.
There is a structure typedefd as shown below.
typedef struct _AT91S_SYS {
AT91_REG AIC_SMR[32]; // Source Mode Register
AT91_REG AIC_SVR[32]; // Source Vector Register
AT91_REG AIC_IVR; // IRQ Vector Register
...
} AT91S_SYS, *AT91PS_SYS;
I have used typedef with structs like } AT91S_SYS;.
What does this additional part does? *AT91PS_SYS; in } AT91S_SYS, *AT91PS_SYS;
Is it a pointer to the struct _AT91S_SYS type?
AT91_REG is a typedef of volatile unsigned int
This just defines the type AT91PS_SYS as a pointer to AT91S_SYS.
The easiest way to understand typedef, by the way, is to read the rest of the declaration as if it were just a variable declaration. But, instead of defining variables, you're defining types using whatever type the variable would have had.
So, for example,
int x, *y, z[5];
defines three variables, int x, int *y and int z[5].
Therefore,
typedef int x, *y, z[5];
defines two types, x == int, y == int * and z == int[5]. Simple!
Yes, you are right, the syntax is equivalent to this:
typedef struct _AT91S_SYS AT91S_SYS;
typedef struct _AT91S_SYS *AT91PS_SYS;
So AT91PS_SYS is a pointer type of AT91S_SYS.
Generally, we use typedef to get alternate names for datatypes.
For example --
typedef long int li; // li can be used now in place of long int
But, what does the below typedef do?
typedef int (*pf) (int, int);
typedef int (*pf) (int, int);
This means that variables declared with the pf type are pointers to a function which takes two int parameters and returns an int.
In other words, you can do something like this:
#include <stdio.h>
typedef int (*pf)(int,int);
int addUp (int a, int b) { return a + b; }
int main(void) {
pf xyzzy = addUp;
printf ("%d\n", xyzzy (19, 23));
return 0;
}
typedef long int li;
assigns alternate name li to type long int.
In exactly the same way
typedef int (*pf) (int, int);
assigns alternate name pf to type int (*) (int, int). That all there is to it.
As you probably noticed, typedef declarations follow the same syntax as, say, variable declarations. The only difference is that the new variable name is replaced by the new type name. So, in accordance with C declaration syntax, the declared name might appear "in the middle" of the declarator, when array or function types are involved.
For another example
typedef int A[10];
declares A as alternate name for type int [10]. In this example the new name also appears "in the middle" of the declaration.
It's a function pointer prototype. You can then declare a function as an argument something like this:
void RegisterCallback(pf your_callback_func);
Then you can can call the function passed as a func ptr:
...
your_callback_func(i, j);
...
The typedef has the name pf and it is for a function pointer that takes two integers as arguments and returns an integer.
typedef works as:
Define unknown type with known types.
So it defines function type that takes two int argument and return int.
I want to convert the libusb.h into PureBasic code and now I have this line:
typedef void (LIBUSB_CALL *libusb_transfer_cb_fn)(struct libusb_transfer *transfer);
What does this typedef do?
Later on there are lines like this:
void LIBUSB_CALL libusb_free_device_list(libusb_device **list, int unref_devices);
Thanks in advance!
LIBUSB_CALL is just a type annotation. It probably doesn't do anything.
This declares a type "f" that is a function pointer returning void and taking "params":
typedef void (*f)(params...)
libusb_transfer_cb_fn is a type representing a function pointer tacking a pointer to a libusb_transfer struct and returning nothing (void).
The syntax for typedef in C is peculiar. What you do is write an ordinary declaration:
int x, *y, z[2];
and then insert the keyword typedef in front. This tells the compiler that, for each variable declared, don't actually declare a variable; instead, make that a new name for the type that the variable would have had, if it were a variable. So:
typedef int x, *y, z[2];
makes x an alias for int, y an alias for int *, and z an alias for int [2].
If you take the typedef off the original line you get:
void (LIBUSB_CALL *libusb_transfer_cb_fn)(struct libusb_transfer *transfer);
(which is only syntactically valid if LIBUSB_CALL is a macro, probably some compiler-specific modifier like __stdcall or __fastcall), which is already a little peculiar because of C's need to parenthesize pointers-to-functions. But it would declare (and define) libusb_transfer_cb_fn as a variable of type "pointer to function taking one argument (the transfer thing) and returning void. So the typedef makes libusb_transfer_cb_fn an alias for that type.
The name obviously (well... :-) ) means: "callback function for libusb after a transfer operation".
The idea would be that a later bit of C code might read something like:
extern libusb_transfer_cb_fn abc_func;
which tells you that there's some global variable abc_func of type "pointer to libusb callback", or:
some_return_type xyz_func(libusb_transfer_cb_fn funcp, int a, char *b) {
struct libusb_transfer x;
... some code that fills in x ...
(*funcp)(&x);
}
What is the use of typedef keyword in C ?
When is it needed?
typedef is for defining something as a type. For instance:
typedef struct {
int a;
int b;
} THINGY;
...defines THINGY as the given struct. That way, you can use it like this:
THINGY t;
...rather than:
struct _THINGY_STRUCT {
int a;
int b;
};
struct _THINGY_STRUCT t;
...which is a bit more verbose. typedefs can make some things dramatically clearer, specially pointers to functions.
From wikipedia:
typedef is a keyword in the C and C++ programming languages. The purpose of typedef is to assign alternative names to existing types, most often those whose standard declaration is cumbersome, potentially confusing, or likely to vary from one implementation to another.
And:
K&R states that there are two reasons for using a typedef. First, it provides a means to make a program more portable. Instead of having to change a type everywhere it appears throughout the program's source files, only a single typedef statement needs to be changed. Second, a typedef can make a complex declaration easier to understand.
And an argument against:
He (Greg K.H.) argues that this practice not only unnecessarily obfuscates code, it can also cause programmers to accidentally misuse large structures thinking them to be simple types.
Typedef is used to create aliases to existing types. It's a bit of a misnomer: typedef does not define new types as the new types are interchangeable with the underlying type. Typedefs are often used for clarity and portability in interface definitions when the underlying type is subject to change or is not of importance.
For example:
// Possibly useful in POSIX:
typedef int filedescriptor_t;
// Define a struct foo and then give it a typedef...
struct foo { int i; };
typedef struct foo foo_t;
// ...or just define everything in one go.
typedef struct bar { int i; } bar_t;
// Typedef is very, very useful with function pointers:
typedef int (*CompareFunction)(char const *, char const *);
CompareFunction c = strcmp;
Typedef can also be used to give names to unnamed types. In such cases, the typedef will be the only name for said type:
typedef struct { int i; } data_t;
typedef enum { YES, NO, FILE_NOT_FOUND } return_code_t;
Naming conventions differ. Usually it's recommended to use a trailing_underscore_and_t or CamelCase.
Explaining the use of typedef in the following example. Further, Typedef is used to make the code more readable.
#include <stdio.h>
#include <math.h>
/*
To define a new type name with typedef, follow these steps:
1. Write the statement as if a variable of the desired type were being declared.
2. Where the name of the declared variable would normally appear, substitute the new type name.
3. In front of everything, place the keyword typedef.
*/
// typedef a primitive data type
typedef double distance;
// typedef struct
typedef struct{
int x;
int y;
} point;
//typedef an array
typedef point points[100];
points ps = {0}; // ps is an array of 100 point
// typedef a function
typedef distance (*distanceFun_p)(point,point) ; // TYPE_DEF distanceFun_p TO BE int (*distanceFun_p)(point,point)
// prototype a function
distance findDistance(point, point);
int main(int argc, char const *argv[])
{
// delcare a function pointer
distanceFun_p func_p;
// initialize the function pointer with a function address
func_p = findDistance;
// initialize two point variables
point p1 = {0,0} , p2 = {1,1};
// call the function through the pointer
distance d = func_p(p1,p2);
printf("the distance is %f\n", d );
return 0;
}
distance findDistance(point p1, point p2)
{
distance xdiff = p1.x - p2.x;
distance ydiff = p1.y - p2.y;
return sqrt( (xdiff * xdiff) + (ydiff * ydiff) );
} In front of everything, place the keyword typedef.
*/
typedef doesnot introduce a new type but it just provide a new name for a type.
TYPEDEF CAN BE USED FOR:
Types that combine arrays,structs,pointers or functions.
To facilitate the portability , typedef the type you require .Then when you port the code to different platforms,select the right type by making changes only in the typedef.
A typedef can provide a simple name for a complicated type cast.
typedef can also be used to give names to unnamed types. In such cases, the typedef will be the only name for said type.
NOTE:-SHOULDNT USE TYPEDEF WITH STRUCTS. ALWAYS USE A TAG IN A STRUCTURE DEFINITION EVEN IF ITS NOT NEEDED.
from Wikipedia:
"K&R states that there are two reasons for using a typedef. First ... . Second, a typedef can make a complex declaration easier to understand."
Here is an example of the second reason for using typedef, simplifying complex types (the complex type is taken from K&R "The C programming language second edition p. 136).
char (*(*x())[])()
x is a function returning pointer to array[] of pointer to function returning char.
We can make the above declaration understandable using typedefs. Please see the example below.
typedef char (*pfType)(); // pf is the type of pointer to function returning
// char
typedef pfType pArrType[2]; // pArr is the type of array of pointers to
// functions returning char
char charf()
{ return('b');
}
pArrType pArr={charf,charf};
pfType *FinalF() // f is a function returning pointer to array of
// pointer to function returning char
{
return(pArr);
}
It can alias another type.
typedef unsigned int uint; /* uint is now an alias for "unsigned int" */
typedef unsigned char BYTE;
After this type definition, the identifier BYTE can be used as an abbreviation for the type unsigned char, for example..
BYTE b1, b2;