[HN Gopher] Show HN: CXXStateTree - A modern C++ library for hie...
       ___________________________________________________________________
        
       Show HN: CXXStateTree - A modern C++ library for hierarchical state
       machines
        
       Hi HN!  I've built
       [CXXStateTree](https://github.com/ZigRazor/CXXStateTree), a modern
       C++ header-only library to create hierarchical state machines with
       clean, intuitive APIs.  It supports: - Deeply nested states -
       Entry/exit handlers - State transitions with guards and actions -
       Asynchronous transitions with `co_await` (C++20 coroutines) -
       Optional runtime type identification for flexibility  It's ideal
       for complex control logic, embedded systems, games, robotics, and
       anywhere you'd use a finite state machine.  I'd love feedback, use
       cases, or contributions from the community!  Repo:
       https://github.com/ZigRazor/CXXStateTree
        
       Author : zigrazor
       Score  : 29 points
       Date   : 2025-07-07 06:06 UTC (3 days ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | jeffreygoesto wrote:
       | Nice and compact. I only wound have two nitpicks:
       | 
       | The Readme sais "zero heap allocations" but the code uses list
       | and unordered map and moves, did you mean "zero allocations after
       | state tree building"?
       | 
       | Also for embedded it would be useful to separate all in/out, dot
       | export etc. to a second library that you can omit on small
       | targets.
        
         | zigrazor wrote:
         | yes, it means "zero allocations after state tree building".
         | Thank you for the suggestions, I think we could separate target
         | with compilation switch. If you want you can open an issue on
         | the repo. Thank you so much
        
       | happyweasel wrote:
       | vcpkg it
        
         | zigrazor wrote:
         | You can open an Issue on that on the repo
         | (https://github.com/ZigRazor/CXXStateTree/issues) so we can
         | track these changes.
         | 
         | Another idea is to create a Python binding with a release of a
         | package
        
       | dgan wrote:
       | i am by no means a C++ expert, but isn't "pragma once" frowned
       | upon?
        
         | kookamamie wrote:
         | No, it is the way. Edit: no one has time for inventing unique
         | names for include guards.
        
           | hdhdjd wrote:
           | Does anyone write those by hand anyway in any kind of project
           | the size where it would matter?
           | 
           | #pragma once is broken by design
        
             | bogwog wrote:
             | I don't understand what you're saying here. #pragma once
             | does the job that include guards used to do, but with less
             | work, and in a less error prone way. How is it broken, and
             | how is the size of a project relevant?
        
               | motorest wrote:
               | > I don't understand what you're saying here. #pragma
               | once does the job that include guards used to do, (...)
               | 
               | They don't. They are not C++ and at most they are
               | compiler-specific.
               | 
               | It's fine if you opt to not write C++ and instead target
               | specific compilers instead. Just don't pretend it's not
               | frowned upon or kosher.
        
               | bogwog wrote:
               | TIL about the existence of a passionate #pragma once
               | hating subculture.
               | 
               | Since you seem to be more knowledgeble about this, I'm
               | curious to know which C++ compilers lack support? I know
               | that at least the 3 big ones do (GCC, Clang, and MSVC)
               | and they have for a very long time.
        
             | quietbritishjim wrote:
             | > Does anyone write those by hand anyway in any kind of
             | project the size where it would matter?
             | 
             | I think you're suggesting that you don't need to make up
             | the names for include guards because all tools / IDEs for
             | C++ write them for you automatically anyway. But that isn't
             | my experience. Many IDEs don't write include guards for you
             | automatically ... because everybody uses #pragma once
             | already.
             | 
             | > #pragma once is broken by design
             | 
             | I think you're referring to the historical problem with
             | #pragma once, which is that it can be hard for the compiler
             | to identify what is _really_ the same file (and therefore
             | shouldn 't be included a second time). If you hard link to
             | the same file, or soft link to it, is it the same? What if
             | the same file is mapped to two different mount points? What
             | if genuinely different files have the same contents (e.g.,
             | because the same library is included from two different
             | installation paths)? In practice, soft/hard links to the
             | same file are easily detectable, and anything more obscure
             | indicates such a weird problem with your setup that you
             | surely have bigger issues. #pragma once is _fine_.
             | 
             | (Historically, it also had the benefit that compilers would
             | know not to even re-read the header, whereas with
             | traditional include guards they would need to re-include
             | the file (e.g. in case the whole file is not wrapped in the
             | #ifdef, or in case something else has undefined it since)
             | only to then discard the contents. I've even seen coding
             | guidelines requiring _external_ include guards wrapped
             | around every use of headers with #include  <...>. Yuck! But
             | modern compilers can work out when include guards are meant
             | to mean that so today that difference probably no longer
             | exists.)
        
           | motorest wrote:
           | > No, it is the way.
           | 
           | No, this is completely wrong. Pragma once is non-standard
           | compiler directive. It might be supported by some compilers
           | such as msvc but technically it is not even C++.
           | 
           | There are only two options: include guards, and modules.
        
             | quietbritishjim wrote:
             | What major compiler does not support it?
        
               | motorest wrote:
               | > What major compiler does not support it?
               | 
               | The whole point is that it's not supported and it's not
               | standard, thus using #pragma once needlessly introduced
               | the risk of having the code break.
               | 
               | You should ask yourself what are you doing and why are
               | you using non-standard constructs that may or may not
               | work, specially when it's rather obvious and trivial to
               | just use include guards. Using #pragma once isn't even
               | qualify as being clever to gain anything.
        
               | phkahler wrote:
               | Maybe you should ask why you're using a non-standard
               | compiler if it's not supported.
               | 
               | Not being part of the official standard doesn't
               | necessarily mean it's not well supported.
        
               | AndriyKunitsyn wrote:
               | The whole point of C/C++ is knowing your environment.
               | It's not Java, it's not TypeScript. It's one level above
               | assembly, and if you change the compiler and things
               | break, then it's your fault.
               | 
               | If the standards still don't have a proper replacement
               | for include guards, then too bad for the standards. The
               | C++ standard wasn't aware of multithreading before C++11,
               | this didn't stop people from writing multithreaded
               | programs.
               | 
               | As to why - #pragma once is just cleaner to look at.
        
             | spacechild1 wrote:
             | Yes, it is non-standard, but I don't know any compiler that
             | does not support it.
        
       | baymotion wrote:
       | Related idea for those using python:
       | https://github.com/baymotion/smax.
        
       ___________________________________________________________________
       (page generated 2025-07-10 23:01 UTC)