How to implement state-machine / automata in C
Implementing a state machine in any programming language requires a great deal of organization in order to keep the code readable and facilitate future extensions of the state machine. This article discusses an approach for implementing state machines in C that relies on macro expansions. This approach is used in the wpa_supplicant and hostapd opensource projects.
Background on C macros
A macro is a fragment of code which has been given a name. Whenever the name is used, it is replaced by the contents of the macro. There are two kinds of macros. They differ mostly in what they look like when they are used. Object-like macros resemble data objects when used, function-like macros resemble function calls. Read more ..
State machine using C macro expansions
This technique of implementing state machines uses "Stringification" of macro arguments to dynamically generate function prototypes for each state.
#include<stdio.h> typedef void *STATE_MACHINE_DATA; #define SM_STATE(machine, state) \ static void sm_ ## machine ## _ ## state ## _Enter(STATE_MACHINE_DATA *sm) #define SM_ENTER(machine, state) \ sm_ ## machine ## _ ## state ## _Enter(machine) /* Will be expanded to sm_SM_INITIALIZE_Enter(STATE_MACHINE_DATA *sm) */ SM_STATE(SM, INITIALIZE) { printf("Initializing the SM\n"); } /* Will be expanded to sm_SM_STATE1_Enter(STATE_MACHINE_DATA *sm) */ SM_STATE(SM, STATE1) { printf("Moved to STATE 1\n"); } /* Will be expanded to sm_SM_STATE2_Enter(STATE_MACHINE_DATA *sm) */ SM_STATE(SM, STATE2) { printf("Moved to STATE 2\n"); } enum { INITIALIZE, STATE1, STATE2 } state; int main() { STATE_MACHINE_DATA SM; /* Will be expanded to sm_INITIALIZE_Enter(SM) */ SM_ENTER(SM, INITIALIZE); /* Will be expanded to sm_SM_STATE1_Enter(SM) */ SM_ENTER(SM, STATE1); return (0); }
What makes this approach interesting are the two following points :
- The code is cleaner and self explanatory.
- The programmer does not need to remember the function name that corresponds to each state.
| Labels: coding, howto |
|

Comment