I'm using a function pointer to delegate states in C.
// states
void state1(int first, int second) {
...
}
void state2(int first, int second) {
...
}
// state pointer
void (*current_state)(int, int);
// state logic
if (condition1) {
current_state = &state_1;
} else if (condition2) {
current_state = &state_2;
}
// do the thing
(*current_state)(1, 2);
Now I'm at a point where the given arguments no longer suffice, so there is a third argument needed. Since I don't want to change all states, I wondered if it is possible to pass a quasi constant parameter along with the pointer. Something like this:
void state3(int first, int second, int third) {
...
}
// state logic
...
else if (condition3) {
// calculate the constant third argument
int param3 = 0;
current_state = &state_3(int, int, param3);
}
I there a way to get this to work?
Well I'm not sure I'd recommend it but you could do this sort of thing:
#include <stdlib.h>
#include <stdio.h>
typedef int pfun();
int alice( int a, int b) { return b; }
int bob( int a, int b, int c) { return c; }
int main( )
{
pfun* f;
f = alice;
printf( "%d\n", f( 1, 2, 3));
f = bob;
printf( "%d\n", f( 1, 2, 3));
return EXIT_SUCCESS;
}
This compiles with
gcc -o funp -Wall funp.c
without warnings and runs correctly.
The point is that a function declaration like
int f();
Says that f is a function that returns an int, with unspecified arguments. The downside is that the compiler cannot check that the arguments are of the correct type.
You could pass a *void
pointer and cast it to the concrete type in the state function. All state functions will have the same signature. Something like this:
// states
struct state1_args {
int first;
int second;
};
struct state2_args {
float first;
float second;
float third;
};
void state1(void* state_args) {
struct state1_args* args = (struct state1_args*)state_args;
use(args->first);
...
}
void state2(void* state_args) {
struct state2_args* args = (struct state2_args*)state_args;
use(args->third);
...
}
// state pointer
void (*current_state)(void*);
// state logic
if (condition1) {
current_state = &state_1;
current_state_args = &args_1;
} else if (condition2) {
current_state = &state_2;
current_state_args = &args_2;
}
// do the thing
(*current_state)(current_state_args);
Wtih the same signature of your
// state pointer
void (*current_state)(int, int);
It is not possible. You have to change your state signature or some how remove an argument from state3.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.