Invoking function from the 2d array of function pointers - arrays

#include <stdio.h>
void test1(){ printf("test1\n"); }
void test2(){ printf("test2\n"); }
void test3(){ printf("test3\n"); }
void test4(){ printf("test4\n"); }
void (*hv_ptr[2])() = {test1,test2};
void (*dev_ptr[2])() = {test3,test4};
void (**ptr[2])() = {hv_ptr, dev_ptr};
int main() {
ptr[0][0];
ptr[0][1];
ptr[1][0];
ptr[1][1];
return 0;
}
I have declared the array of pointers to function pointers. But with this code, functions are not getting called. Kindly let me know what is going wrong here.

ptr is an array of pointers to pointers to functions, so ptr[0] is a pointer to a pointer to a function, so ptr[0][0] is a pointer to a function.
Thus, in the expression statement ptr[0][0];, the expression is just a pointer to a function. It does not contain a function call.
ptr[0][0](); is a call to the function pointed to by ptr[0][0].

Related

Volatile Keyword in function pointers

I have doubts about the use of Volatile Keyword in function pointers.
I don't know if in this case, function pointers should be volatile
I use function pointers so that the same function, for example sendCommand() can use different uart's functions.
My code would be like this
//Function pointer
void (*volatile ptr_uart_putc) (unsigned char);
//Set function pointer
void uartConfig( void(*aPtr_uart_putc)(unsigned char) ){
ptr_uart_putc = aPtr_uart_putc ;
}
void sendCommand(unsigned char aCommand){
ptr_uart_putc(aCommand);
}
So in main I would do:
main(){
uartConfig(uart0_putc);
sendCommand('a');
uartConfig(uart1_putc);
sendCommand('b');
}

double pointers error in C when compiling error when using void as well

I'm new to C and im currently learning about pointers.
I'm not sure why I am getting an error with the following sections of code in regards to pointers :
char ch;
char** pointer;
pointer = &ch;
and
int function1(void)
{
return 42.0;
}
void function2(void)
{
void (*pointer)(int);
pointer = &function1;
...
}
Any help will be appreciated :)
The very first problem is that you are using a double pointer in char** pointer ,as you are not storing the address of some other pointer so you should use char *pointer instead.
Then your function1 has return type as int but you are returning a float value ,although it won't give you any error but it can create some logical issues in your program,so better to properly write the return type in function definition and its prototype.
Then the next problem is in the function2,your function1 returns int but does not take any arguments but your function pointer return void and take int ,so you should better modify this to
int (*pointer)(void);
and then store the address of function1 in pointer ,it will work fine.
* is a single pointer and ** is a pointer to pointer.
So instead of
char** pointer;
It should be:
char* pointer;
In the second case, the function pointer prototype is not matching the prototype of the function it is pointing to.
So instead of
void (*pointer)(int);
it should be:
int (*pointer)(void);
you second section have some mistakes
you function1() return int and not take args
but your fucntion ptr return void and take int
so change it to:
int (*pointer)(void);
pointer = &function1;

pointer to function pointer - expression must be a modifiable lvalue

I want to acquire address of a needed function in function Check_Commands, put it in pointer fptr, and then call it. But, when trying to compile this code, I get following message:
"Error[Pe137]: expression must be a modifiable lvalue"
am I missing something?
void main(void)
{
...
void(*fptr)(CmdDataType);
Check_Commands(&fptr);
(*fptr)(&CmdData);
}
void Check_Commands(void (**ptrfuncptr)(CmdDataType))
{
...
**ptrfuncptr=&DispFirmware;
...
}
void DispFirmware(CmdDataType *CmdData_ptr)
{
...
}
This:
**ptrfuncptr=&DispFirmware;
should just be
*ptrfuncptr = DispFirmware;
Also there's no need to dereference a function pointer when calling, the name of a function can be thought of as a pointer to it so an ordinary call works just like that through a pointer.
There were a couple issues with your code. Here's the fixed version:
void main(void)
{
CmdDataType CmdData;
void (*fptr)(CmdDataType *);
Check_Commands(&fptr);
(*fptr)(&CmdData);
}
void Check_Commands(void (**ptrfuncptr)(CmdDataType *))
{
*ptrfuncptr=&DispFirmware;
}
void DispFirmware(CmdDataType *CmdData_ptr) { }
fptr is a pointer to a function which takes a CmdDataType pointer as a parameter, so that needed to be fixed.
And in the function Check_Commands the function pointer needs to be dereferenced only once.

Crash while using array of function pointers in a structure

When I use an array of function pointers in a structure, the program crashes.
#include <stdio.h>
typedef void (*FUNCPTR)(void);
void Function_1()
{
printf(" In Function_1 \n");
}
void Function_2()
{
printf(" In Function_2 \n");
}
typedef struct St_FUNCPTR
{
FUNCPTR xxx[2];
}ST_FUNCPTR;
FUNCPTR fnptr1[2] =
{
Function_1,
Function_2
};
ST_FUNCPTR fnptr =
{
fnptr1
};
/* The intention is to call Function_1(); through array of function
pointers in the structure. */
int main()
{
// to call Function_1();
fnptr.xxx[0]();
return 0;
}
If the structure is defined like below, it works fine.
ST_FUNCPTR fnptr =
{
{Function_1,Function_2},
};
Where is my problem?
My bets are here:
ST_FUNCPTR fnptr =
{
fnptr1
};
What you are trying to do is initialize structure, which element is an array with an array. fnptr1 is an array of pointers to function.
With your edit it's for sure. You can't initialize array with another array like you cant say that int a1[10]=int b[10].
For clarification: fnptr1 here is pointer constans to pointer to function.And it goes to xxx[0] being converted to pointer to the function by the way.
What code does next, it takes address of that pointer, fnptr.xxx[0] , treats it like a pointer to function and calls it with (). But theres no function under that address, just pointer to the function, so there's a crash.

Function Returning Itself

Is it possible to declare some function type func_t which returns that type, func_t?
In other words, is it possible for a function to return itself?
// func_t is declared as some sort of function pointer
func_t foo(void *arg)
{
return &foo;
}
Or would I have to use void * and typecasting?
No, you cannot declare recursive function types in C. Except inside a structure (or an union), it's not possible to declare a recursive type in C.
Now for the void * solution, void * is only guaranteed to hold pointers to objects and not pointers to functions. Being able to convert function pointers and void * is available only as an extension.
A possible solution with structs:
struct func_wrap
{
struct func_wrap (*func)(void);
};
struct func_wrap func_test(void)
{
struct func_wrap self;
self.func = func_test;
return self;
}
Compiling with gcc -Wall gave no warnings, but I'm not sure if this is 100% portable.
You can't cast function pointers to void* (they can be different sizes), but that's not a problem since we can cast to another function pointer type and cast it back to get the original value.
typedef void (*fun2)();
typedef fun2 (*fun1)();
fun2 rec_fun()
{
puts("Called a function");
return (fun2)rec_fun;
}
// later in code...
fun1 fp = (fun1)((fun1)rec_fun())();
fp();
Output:
Called a function
Called a function
Called a function
In other words, is it possible for a function to return itself?
It depends on what you mean by "itself"; if you mean a pointer to itself then the answer is yes! While it is not possible for a function to return its type a function can return a pointer to itself and this pointer can then be converted to the appropriate type before calling.
The details are explained in the question comp.lang.c faq: Function that can return a pointer to a function of the same type.
Check my answer for details.
Assume the function definition
T f(void)
{
return &f;
}
f() returns a value of type T, but the type of the expression &f is "pointer to function returning T". It doesn't matter what T is, the expression &f will always be of a different, incompatible type T (*)(void). Even if T is a pointer-to-function type such as Q (*)(void), the expression &f will wind up being "pointer-to-function-returning-pointer-to-function", or Q (*(*)(void))(void).
If T is an integral type that's large enough to hold a function pointer value and conversion from T (*)(void) to T and back to T (*)(void) is meaningful on your platform, you might be able to get away with something like
T f(void)
{
return (T) &f;
}
but I can think of at least a couple of situations where that won't work at all. And honestly, its utility would be extremely limited compared to using something like a lookup table.
C just wasn't designed to treat functions like any other data item, and pointers to functions aren't interchangeable with pointers to object types.
what about something like this:
typedef void* (*takesDoubleReturnsVoidPtr)(double);
void* functionB(double d)
{
printf("here is a function %f",d);
return NULL;
}
takesDoubleReturnsVoidPtr functionA()
{
return functionB;
}
int main(int argc, const char * argv[])
{
takesDoubleReturnsVoidPtr func = functionA();
func(56.7);
return 0;
}
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
typedef void *(*fptr)(int *);
void *start (int *);
void *stop (int *);
void *start (int *a) {
printf("%s\n", __func__);
return stop(a);
}
void *stop (int *a) {
printf("%s\n", __func__);
return start(a);
}
int main (void) {
int a = 10;
fptr f = start;
f(&a);
return 0;
}
It is not possible for a function to return itself by value. However it is possible itself to return by a pointer.
C allows to define function types that take undefined number of parameters and those those types are compatible with function types that take defined parameters.
For example:
typedef void fun_t();
void foo(int);
fun_t *fun = foo; // types are fine
Therefore the following function would work.
void fun(void (**ptr)()) {
*ptr = &fun;
}
And below you can find the exemplary usage:
#include <stdio.h>
void fun(void (**ptr)()) {
puts("fun() called");
*ptr = &fun;
}
int main() {
void (*fp)();
fun(&fp); /* call fun directly */
fp(&fp); /* call fun indirectly */
return 0;
}
The code compiles in pedantic mode with no warnings for C89 standard.
It produces the expected output:
fun() called
fun() called
There's a way, you just try this:
typedef void *(*FuncPtr)();
void *f() { return f; }
int main() {
FuncPtr f1 = f();
FuncPtr f2 = f1();
FuncPtr f3 = f2();
return 0;
}
If you were using C++, you could create a State object type (presuming the state machine example usage) wherein you declare an operator() that returns a State object type by reference or pointer. You can then define each state as a derived class of State that returns each appropriate other derived types from its implementation of operator().

Resources