Live data from Hacker News

C++ State Machines

beza1e1.tuxen.de

11–20 of 29 posts

Re: C++ State Machines

#11
post #4
post #3

If you're not willing to develop all the boilerplate code to encode your states, transitions, etc. Boost has two libraries to offer : Boost Statechart and Meta State Machine. One of my favorite question on Stack Overflow compares both: https://stackoverflow.com/questions/4275602/boost-statechart... . As with most Boost libraries, you're in for some serious headache if you decide to use them (or is it just me?) but it…

Boost.SML (which is experimental) has garnered a lot of attention lately as a modern take on C++ state machines that can replace both of the options you raised. https://boost-experimental.github.io/sml/ Unfortunately I haven't seen any compelling real world usage of any of these libraries, and the documentation for SML leaves a lot to be desired.

Seeing those examples made me realize how much I hate Modern C++, or just C++ in general.

This is so belaboured; there's an abundance of what looks like line noise to me. It lacks any sense of grace whatsoever.

Re: C++ State Machines

#12

Simulink, and specifically stateflow, is commonly used in the aerospace industry to graphically create state machines that can be autocoded into high performance C or C++ code. I use simulink and stateflow everyday to create flight control software. I feel like more software engineers should learn how to use graphical coding tools, as IMO it's so much easier to represent complex state machines graphically. It's a sha…

I'd rather have tools that can take code which implements a state machine and produce a statechart than go the other way around. There are a few tools which will go from statecharts to code and they've been around a while but never seemed to get very popular. I think dealing with a complex system as a statechart is potentially harder than dealing with code.

That said, my friend works on satellite software implemented with state machines. He was saying the high reliability of the system is mainly attributed to the requirement that systems be designed as statecharts first, which forces the designs to remain simple and analyzable.

Re: C++ State Machines

#13
post #3

If you're not willing to develop all the boilerplate code to encode your states, transitions, etc. Boost has two libraries to offer : Boost Statechart and Meta State Machine. One of my favorite question on Stack Overflow compares both: https://stackoverflow.com/questions/4275602/boost-statechart... . As with most Boost libraries, you're in for some serious headache if you decide to use them (or is it just me?) but it…

Last I looked at Boost's offerings for state machines, my team and I found the offerings lacking. I forget exactly what it was missing (it's been 6-7 years and 4 jobs ago). May have been needing to perform actions on leaving a state, but not sure.

Edit: Boost is my first stop for non-standard C++ libs, but this time the offering was lacking. Previously also had issues with the date/time libs. Like they got 90% of the way there, and then didn't quite finish. Example: time zone handling. Has all of the infrastructure to support it, but no facility to really provide the necessary data. Also, their CSV of timezones was not historical, so broke down trying to do historical work for something like an energy contract in finance, where it was necessary to know if there were 23, 24 or 25 hours in a calendar day (or other value!) in a given year. Also, the interfaces for posix_time and local_date_time are a little clunky. I ended up with a facade that exposed an API more like Python's datetime lib. We also had a timezone loader to handle Olson TZ databases for the historical TZ info (and future updates) for both Linux and Windows.

Re: C++ State Machines

#14
Harel Statecharts are mentioned elsewhere in this thread, and I endorse them. IMO they're a really great way to model your design.

IIRC Quantum Leaps [Samek; also mentioned in this thread] is similar to statecharts.

I've used Rational Rhapsody for C++ and I think it's actually pretty good. But there be dragons there. UML alone is a tough sell to some engineering crowds, much less generating code from diagrams. Holy wars abounds.

While searching for related info to this post I discovered that W3 has a relevant specification [1]. But I suppose it makes sense, IBM is a player here and they love XML there.

[1] https://www.w3.org/TR/scxml/

Re: C++ State Machines

#15

Simulink, and specifically stateflow, is commonly used in the aerospace industry to graphically create state machines that can be autocoded into high performance C or C++ code. I use simulink and stateflow everyday to create flight control software. I feel like more software engineers should learn how to use graphical coding tools, as IMO it's so much easier to represent complex state machines graphically. It's a sha…

>Mathworks

I used Simulink and Speedgoat (and LabView!) for many years. Oh how I long to create a startup that would improve on all of these dinosaur-like tools. Seriously if anyone wants to disrupt these entrenched, inertial companies, look me up. There are sooo many places to improve and you're right there's almost no competition. Trust me, I looked for it every few months when I ran into the limitations of these packages. I accept them for what they are, but they could be so much better!

Re: C++ State Machines

#16
For his logical combination problem, I think the solution is to use enums:

   State nextState(bool a, bool b, bool c, bool d)
   {
      enum A { A_NO = 0, A_YES = 1 } As[] = { A_NO, A_YES };
      enum B { B_NO = 0, B_YES = 2 } Bs[] = { B_NO, B_YES };
      enum C { C_NO = 0, C_YES = 4 } Cs[] = { C_NO, C_YES };
      enum D { D_NO = 0, D_YES = 8 } Ds[] = { D_NO, D_YES };
      switch (As[a]) + Bs[b] + Cs[c] + Ds[d])
      {
         case A_NO  + B_NO  + C_NO  + D_NO : return X; // 0
         case A_NO  + B_NO  + C_NO  + D_YES: return X; // 1
         case A_NO  + B_NO  + C_YES + D_NO : return X; // 2
         case A_NO  + B_NO  + C_YES + D_YES: return X; // 3
         case A_NO  + B_YES + C_NO  + D_NO : return X; // 4
         case A_NO  + B_YES + C_NO  + D_YES: return X; // 5
         case A_NO  + B_YES + C_YES + D_NO : return X; // 6
         case A_NO  + B_YES + C_YES + D_YES: return X; // 7
         case A_YES + B_NO  + C_NO  + D_NO : return X; // 8
         case A_YES + B_NO  + C_NO  + D_YES: return X; // 9
         case A_YES + B_NO  + C_YES + D_NO : return X; // 10
         case A_YES + B_NO  + C_YES + D_YES: return X; // 11
         case A_YES + B_YES + C_NO  + D_NO : return X; // 12
         case A_YES + B_YES + C_NO  + D_YES: return X; // 13
         case A_YES + B_YES + C_YES + D_NO : return X; // 14
         case A_YES + B_YES + C_YES + D_YES: return X; // 15
      }
   }
Let the compiler reorgonise the switch for efficiency. Do not: skip combination. Do not: reorder. Do not: remove the number that help see we got all cases. The compiler will error out if a case is duplicated. I wish we could make it detect missing cases too!

Re: C++ State Machines

#17

Simulink, and specifically stateflow, is commonly used in the aerospace industry to graphically create state machines that can be autocoded into high performance C or C++ code. I use simulink and stateflow everyday to create flight control software. I feel like more software engineers should learn how to use graphical coding tools, as IMO it's so much easier to represent complex state machines graphically. It's a sha…

I'd rather have tools that can take code which implements a state machine and produce a statechart than go the other way around. There are a few tools which will go from statecharts to code and they've been around a while but never seemed to get very popular. I think dealing with a complex system as a statechart is potentially harder than dealing with code. That said, my friend works on satellite software implemented…

> the high reliability of the system is mainly attributed to the requirement that systems be designed as statecharts first, which forces the designs to remain simple and analyzable.

This can also be due to the fact that statecharts inherently require every transition and event to be mapped, which is more up-front work than most programmers do on their state machines. Need a feature that requires a new state? Instead of glomming it onto the code (and, in a complex codebase, probably missing one transition or another), you have to do the work of putting it into the state diagram and handling every transition into and out of that state (from every one of the connecting states in the graph). From there, you have a much more completely accounted list of the changes that have to be made to other states, in addition to a more complete list for testing the resulting code.

> dealing with a complex system as a statechart is potentially harder than dealing with code.

Yes, but it strikes me as harder in the same way that it's more difficult to get code to build when you have a strict linter and a strict static analysis tool in the pipeline; when reliability is worth a bit of developer-convenience-cost, we add procedures such that making changes takes more work at the beginning.

Re: C++ State Machines

#18
post #6
post #5

Earlier quoted context omitted.

How do you manage combinatorial explosion as states increase?

The proposed state table is hardly more scalable. It's obviously not infinitely scalable but In my proposed way, you only have to specify the cases where a state transition actually occurs.

What you describe feels more like case classes.

Re: C++ State Machines

#20
post #9
post #4

Earlier quoted context omitted.

Boost.SML (which is experimental) has garnered a lot of attention lately as a modern take on C++ state machines that can replace both of the options you raised. https://boost-experimental.github.io/sml/ Unfortunately I haven't seen any compelling real world usage of any of these libraries, and the documentation for SML leaves a lot to be desired.

I have been using SML in production for a little over a year now without issues, mostly for protocol machines. I agree the documentation is not great though, you kind of have to go over the example code and try to figure things out on your own. Using embedded data for keeping state (e.g. counters, etc; see https://boost-experimental.github.io/sml/examples/index.html... ) along with injecting std::functions to use as…

I didn’t find a good way to handle unexpected events with SML. I know there is supposed to be a special catch all event which can do that, but that’s only for the case the event is not used in the entire FSM, which makes it pretty useless. Thinking of rolling my own based on std::variant now.
Post reply on HN