
Andrey Semashev wrote:
Dear All,
I have just spent a few minutes comparing an ad-hoc FSM implementation with an implementation using the proposed library. The example that I've used is the USB device state machine, which I recently had to understand for an embedded application, and I've put an image of the state graph here:
[snip]
Here is my ad-hoc implementation (note that I haven't tried to even compile any of this code):
[snip code]
Well, your code is not an FSM. I mean, the usb_device behavior does not in any way depend on its state. I could simply remove the state variable and have the same result.
If I had realised sooner how degenerate that particular example was going to turn out I would have chosen something else. But I realised too late, and I thought it was better to use a real application than a contrived one. I will try to come up with another example before the end of the review period so that we can discuss the real problem and not be sidetracked by this. I do hope that others will also post some code.
Some of the verbosity would go if I put the common events (e.g. PowerOff) into a base class, but that adds verbosity of its own.
Why? Base classes for states help a lot to reduce code redundancy. I've attached a slightly modified version of the code above, with base classes and library-provided events (this allows you not to define event classes, which also reduces the code). See usb_fsm_state_based.cpp.
Unfortunately I'm unable to easily read attachments because these links:
A non-text attachment was scrubbed... Name: usb_fsm_state_based.cpp Type: text/x-c++src Size: 2214 bytes Desc: not available URL: <http://lists.boost.org/MailArchives/boost/attachments/20080817/737190e0/attachment.bin>
still don't work. I'll try to find your code in one of the list archives.
IMO, undefined behavior usually is a design flaw, and this case is clearly one of the "usual" ones. Otherwise, like I said, you don't need FSM, because its whole purpose is to _define_ the behavior.
I disagree. If I have a guarantee of how the environment will behave it is unnecessary to check it, except perhaps in some sort of debug mode. Picking up on one of Dave's comments, do you put a test in every function that takes a pointer to test whether you have been passed a null? Of course, when the behaviour of the environment is not guaranteed then I do need to check. If the scope of the proposed library is intended to be limited to applications where the environment is untrusted, please make a note of that in the documentation. Anyway, I will make sure that my next example is of the "untrusted environment" type. Regards, Phil. P.S. Many thanks to Dave A for fielding a whole series of messages while I was wasting my Sunday morning writing my tax return....