SkillAgentSearch skills...

StateMachine

State Machine Design in C++

Install / Use

/learn @endurodave/StateMachine
About this skill

Quality Score

0/100

Category

Design

Supported Platforms

Universal

README

License MIT conan Ubuntu conan Ubuntu conan Windows

State Machine Design in C++

A compact C++ finite state machine (FSM) implementation that's easy to use on embedded and PC-based systems.

Table of Contents

Preface

Originally published on CodeProject at: <a href="https://www.codeproject.com/Articles/1087619/State-Machine-Design-in-Cplusplus"><strong>State Machine Design in C++</strong></a>

Based on original design published in C\C++ Users Journal (Dr. Dobb's) at: <a href="http://www.drdobbs.com/cpp/state-machine-design-in-c/184401236"><strong>State Machine Design in C++</strong></a>

Related repositories

Related repositories containing alternative state machine implementations.

| Project | Description | | :--- | :--- | | Active-Object State Machine in C++ | A compact active-object C++ finite state machine providing RAII-safe asynchronous dispatch and pub/sub signals. | | State Machine Design in C | A compact C language finite state machine (FSM) implementation. | | State Machine Design in C++ (Compact) | A compact C++ finite state machine (FSM) implementation. |

Getting Started

CMake is used to create the project build files on any Windows or Linux machine. The state machine source code works on any C++ compiler on any platform.

  1. Clone the repository.
  2. From the repository root, run the following CMake command:
    cmake -B Build .
  3. Build and run the project within the Build directory.

Introduction

<p>In 2000, I wrote an article entitled &quot;<em>State Machine Design in C++</em>&quot; for C/C++ Users Journal (R.I.P.). Interestingly, that old article is still available and (at the time of writing this article) the #1 hit on Google when searching for C++ state machine. The article was written over 15 years ago, but I continue to use the basic idea on numerous projects. It&#39;s compact, easy to understand and, in most cases, has just enough features to accomplish what I need.&nbsp;</p> <p>This article provides a new implementation with updated features at the slight expense of a bit more code. I&#39;ll also correct the errors in the original implementation because if you&#39;re really tight on storage it&rsquo;s still be a viable solution. Both designs are table driven suitable for any platform, embedded or PC, with any C++ compiler.&nbsp;</p> <p>Why another state machine design? Certainly by now there&#39;s an existing implementation out there that can be used, right? Maybe. On occasion, I&#39;ll try a new state machine and find it doesn&#39;t fit my needs for one reason or another. For me, the problem usually boils down to one or more of the following:</p> <ol> <li><strong>Too large</strong> &ndash; the resulting implementation takes too much code space to justify on an embedded platform.</li> <li><strong>Too complex</strong> &ndash; excessive templates or requires adoption of a complete framework to use the state machine.</li> <li><strong>No compiler support </strong>&ndash; relies upon new C++ language features not supported by the compiler.</li> <li><strong>High learning curve</strong> &ndash; some require quite a lot of effort in this regard.&nbsp;</li> <li><strong>Difficult syntax </strong>&ndash; non-intuitive state machine expression with hard to diagnose compiler errors.&nbsp;</li> <li><strong>External libraries</strong> &ndash; relies upon external libraries that add size or aren&#39;t supported on the platform.</li> <li><strong>Too many features </strong>&ndash; full UML compliance isn&#39;t required and therefore exceeds the basic needs of the problem at hand.&nbsp;</li> <li><strong>No event data</strong> &ndash; can&#39;t send unique event data to a state function.</li> <li><strong>Central event handler </strong>&ndash; a single event handling function and a switch statement handles events for each class.</li> <li><strong>No type safety </strong>&ndash; requires manual typecasting the event data based on an enumeration.</li> <li><strong>Limited transition rules </strong>&ndash; no support for event ignored and can&#39;t happen event transitions.&nbsp;</li> <li><strong>No thread-safety </strong>&ndash; the code is not thread-safe.&nbsp;</li> </ol> <p>Don&#39;t get me wrong, some implementations are quite impressive and suitable for many different projects. Every design has certain tradeoffs and this one is no different. Only you can decide if this one meets your needs or not. I&#39;ll try to get you bootstrapped as quickly as possible through this article and sample code. This state machine has the following features:</p> <ol> <li><strong>Compact</strong> &ndash; the StateMachine class is not a template &ndash; only 448 bytes of code on Windows. Templates are used sparingly.&nbsp;</li> <li><strong>Transition tables</strong> &ndash; transition tables precisely control state transition behavior.&nbsp;</li> <li><strong>Events </strong>&ndash; every event is a simple public instance member function with any argument types.&nbsp;</li> <li><strong>State action</strong> &ndash; every state action is a separate instance member function with a single, unique event data argument if desired.</li> <li><strong>Guards/entry/exit actions</strong> &ndash; optionally a state machine can use guard conditions and separate entry/exit action functions for each state.</li> <li><strong>State machine inheritance </strong>&ndash; supports inheriting states from a base state machine class.&nbsp;</li> <li><strong>State function inheritance </strong>&ndash; supports overriding a state function within a derived class.&nbsp;</li> <li><strong>Macros </strong>&ndash; optional multiline macro support simplifies usage by automating the code &quot;machinery&quot;.</li> <li><strong>Type safe </strong>&ndash; compile time checks catch mistakes early. Runtime checks for the other cases.&nbsp;</li> <li><strong>Thread-safe </strong>&ndash; adding software locks to make the code thread-safe is easy.</li> </ol> <p>This state machine design is not trying to achieve a full UML feature set. It is also not a Hierarchical State Machine (HSM). Instead, its goal is to be relatively compact, portable, and easy to use traditional Finite State Machine (FSM) with just enough unique features to solve many different problems.&nbsp;</p> <p>The article is not a tutorial on the best design decomposition practices for software state machines. I&#39;ll be focusing on state machine code and simple examples with just enough complexity to facilitate understanding the features and usage.&nbsp;</p>

Background

<p>A common design technique in the repertoire of most programmers is the venerable finite state machine (FSM). Designers use this programming construct to break complex problems into manageable states and state transitions. There are innumerable ways to implement a state machine.&nbsp;</p> <p>A switch statement provides one of the easiest to implement and most common version of a state machine. Here, each case within the switch statement becomes a state, implemented something like:</p> <pre lang="c++"> switch (currentState) { case ST_IDLE: // do something in the idle state break; case ST_STOP: // do something in the stop state break; // etc... }</pre> <p>This method is certainly appropriate for solving many different design problems. When employed on an event driven, multithreaded project, however, state machines of this form can be quite limiting.</p> <p>The first problem revolves around controlling what state transitions are valid and which ones are invalid. There is no way to enforce the state transition rules. Any transition is allowed at any time, which is not particularly desirable. For most designs, only a few transition patterns are valid. Ideally, the software design should enforce these predefined state sequences and prevent the unwanted transitions. Another problem arises when trying to
View on GitHub
GitHub Stars171
CategoryDesign
Updated14h ago
Forks46

Languages

C++

Security Score

100/100

Audited on Mar 27, 2026

No findings