Function pointers - Simple use without confusion in C Programming
Good way to define function pointer
In an embedded project with different programs, pointer is of great use. For example, in an embedded project, one may want to do a soft reset. Which means nothing but jumping back to the starting address(most of the cases, the reset vector = address 0). In C program, this can be achieved by using a pointer, assign it to value 0 and call.
void (*pSoftReset)(void); /* Define a function pointer */
pSoftReset = (void (*)(void))0; /* Assign address 0 to pointer */
pSoftReset(); /* Function call using pointer */
In the above snippet, in line 1, a function pointer is defined. In line 2, pointer is initialized with address. Note the typecasting. 0 integer is typecast-ed to a function pointer with address value 0. Then, the function is called. It will never return as the initialization routines will initialize all the variables, stack etc.
The same code can also be written in single line as
((void (*)(void))0)(); /* Typecast address 0 to pointer and call */
Here integer is typecast-ed and called at the same time.
This function pointer definition, typecasting etc might be difficult to read for many. Because of this code may be less readable. To avoid this we may use the typedef functionality to define new types as below.
typedef void (*typFPtr)(void); /* Define new type typFPtr as pointer to a function */
typFPtr pSoftReset = (typFPtr)0; /* Assign address 0 */
pSoftReset(); /* Call using pointer */
In order to avoid confusion and improve readability, it is better to define new types and use it instead of directly using the function prototype. However, please note that this may also cause some confusion as the '*' is missing in declaration of variable and typecast. Alternately, it can also be done as below.
typedef void (typFN)(void); /* Define new type typFN as pointer to a function */
typFN *pSoftReset = (typFN *)0; /* Define pointer to function and Assign address 0 */
pSoftReset(); /* Call using pointer */
To conclude, definition and use of complex function pointers can be achieved by using typedef. Some examples are mentioned below.
/* Below definiton is a function pointer fp which
* will accept a pointer to a function which takes
* pointer to int as argument, returns void and
* another int as second parameter and returns a
* function pointer which takes int as argument
* and returns pointer to int */
int *(*((*fp)(void (*)(int*), int *)))(int);
/* Uning typedef it can be simplified as below */
typedef int *typFun_pint_int(int);
typedef void typFun_void_pint_int(int*);
typFun_pint_int * fp_simplified(typFun_void_pint_int *, int *);
/* Here it is clear what is the return type
and what are the arguments */
In my next post, I will list some examples of using function pointers. Initially, I thought of adding it here. But, it is too late for me now. So thought of writing it as another post.
No comments :
Post a Comment