Understanding function pointers

I am trying to find a simple way to use pointer functions to build a FSM. I could not get many of the C examples on the net to compile in Arduino like this one:

typedef enum {STATE_A = 0, STATE_B} State_type;
// table with pointers to to the function
void (*state_table[]) = {state_a, state_b}; // this line gives error message

State_Type curr_state;

Setup() {}
Loop() {
state_table{curr_state]();
}

void state_a(){
// run state code
curr_state = STATE_B
}

void state_b(){
// run state code
curr_state = STATE_A
}

Please advise how to fix this version.

I managed to get the attached FunctionPointers-A working. But this variation, FunctionPointers-B, compiles but does not work.

I would appreciate it if someone could explain what my errors are.
Further what is a good text book explaining function pointers in (arduino) embedded systems?
Thank you!

FunctionPointers-A.ino (505 Bytes)

Function Pointers-B.ino (541 Bytes)

typedef enum {STATE_A = 0, STATE_B} State_type;

State_type curr_state;

void state_a()
{
  Serial.println("in A");  // for testing
  delay(1000);  // for testing
  curr_state = STATE_B;
}

void state_b()
{
  Serial.println("in B");  // for testing
  delay(1000);  // for testing
  curr_state = STATE_A;
}

void (*state_table[])() = {state_a, state_b};

void setup()
{
  Serial.begin(115200);
}

void loop()
{
  state_table[curr_state]();
}

Sometimes it's difficult to figure out what is being defined, especially in complex data definitions. For example, Hackscribble's statement:

void (*state_table[])() = {state_a, state_b};

can be hard to figure out. After reading about the Right-Left Rule:

http://jdurrett.ba.ttu.edu/3345/handouts/RL-rule.html

you can verbalize the definition as:

state_table is an array of two pointers to function that return void

It gets easier with practice.

I quite often use typedefs for function pointers, which keeps the declarations readable and makes changes easy.

typedef void (*vvFunction)();

vvFunction table[] =  {state_a, state_b};

Whandall:
I quite often use typedefs for function pointers, which keeps the declarations readable and makes changes easy.

typedef void (*vvFunction)();

vvFunction table[] =  {state_a, state_b};

This is probably a rhetorical questions, but which do you think is easier for a beginner to read and understand? If these two lines were separated with a few lines of code (agreed...they shouldn't be), you still have to "splice" the two lines together to understand the data definition, which is why I would just use the single-line definition. It's really a matter of style as much as anything.

econjack:
but which do you think is easier for a beginner to read and understand?

In anything other than a trivial program the chances are that one is going to need a variable to hold the function pointer as well as the function pointer array. This variable needs to use the same function pointer definition so it makes sense to use a typdef rather than write out the same function pointer definition many many times.

I feel an array of some objects (here function pointers defined seperate) is less cryptic than defining all in one place.
Better naming than my lame try of the used type can help too.

We are looking at the most simple type of function, no parameters and no return value.
With more parameters and complicated return types those statements can get pretty hard to read,
even to experts.
Think of a pointer to a function returning some function...

If you use the function pointers in many places, passing them around etc. it's a pita to change all usages,
if the function interface changes even slightly.

I use that technique more in respect to maintainability/extendability and experienced typedefs in the function pointer context as helpful.

Whandall:
I quite often use typedefs for function pointers, which keeps the declarations readable and makes changes easy.

typedef void (*vvFunction)();

vvFunction table[] =  {state_a, state_b};

Certainly the naming (using Whandall's easy-to-read example) of the function pointer type and associated array name(s) may also aid in identifying what the programmer was doing (i.e. make less obscure):

functionPtrTypeName  meaningfulArrayName[] = { ...

Great!
Many thanks for you guy's help. I got all my FSM states now 'ticking'.
What about a good book about this subject (and examples)?
Hans

One more question:

How can I select states also by number (instead of an enum / State_type)?

i.e curr_state = STATE_A will point to state-a, but curr_state = 0 gives an error (despite STATE_A = 0)

Just use a byte or int as an index.

int selected = 1;

state_table[selected]();
void (*state_table[]) = {state_a, state_b}; // this line gives error message

So, state table is an array of pointers to void. That's not what you want. You need an array of pointers to functions returning void.

void (*state_table[])() = {state_a, state_b}; // this line gives error message

Try this:

typedef enum {STATE_A = 0, STATE_B = 1} State_type;
// table with pointers to to the function

extern void state_a(); // forward declaration
extern void state_b(); // forward declaration

void (*state_table[])() = {state_a, state_b}; // this line gives error message

State_type curr_state;

void setup() {}
void loop() {
  state_table[curr_state]();
}

void state_a() {
  // run state code
  curr_state = STATE_B;
}

void state_b() {
  // run state code
  curr_state = STATE_A;
}

It compiles for me.