
David Abrahams <dave <at> boost-consulting.com> writes:
This is certainly doable. However, I'm unsure whether the current design allows a you-don't-pay-for-what-you-don't-use implementation of such a feature. Plus, I'm still not convinced that this feature would be used more than rarely. Do you have some real-world use cases in mind?
Unfortunately I'm not so familiar with what exit actions in FSMs are typically used for, but from an abstract point of view I don't think of resource releasing as an "action". If you were writing this stuff in a GC'd language, for the most part, you wouldn't devote any exit action code to resource releases.
I don't think so. A non-shareable resource (e.g. a file) you almost always need to release immediately after you are done using it (because someone else might want to access it while your program is still running). The same is true for shareable resources that are limited by other factors than memory (e.g. SQL connections).
So I figure there must be some other reason people want exit actions ...
In my experience you typically do the following stuff in exit actions: For the most part you release resources, sometimes bump a counter here and there and, yes, under rare circumstances you also execute stuff that can fail. I guess we agree that the same is true for destructors.
... , and since they seem symmetrical to entry actions in some ways, I don't see why you'd want to prohibit exceptions there.
For the same reasons that class constructors and destructors are asymmetrical in this regard as well.
If anything, I'd want to prohibit exceptions in entry actions, since those can lead to the FSM being in a state from which it's impossible to continue.
Interesting, it seems "failure-proof" entry actions would be an inevitable consequence when you allow failing exit actions.
At least with exit actions, you can stay where you are and keep all your FSM's abstract invariants intact.
As I have already pointed out: Only if your machines are flat and non- orthogonal, right? My approach is almost symmetrical to yours, isn't it? Since I allow failing entry actions I am forced to disallow failing exit actions. With your approach exit actions can fail what forces you to disallow failing entry actions. In both approaches allowing the failure-proof action to suddenly fail can result in an FSM having an invalid state from where it is impossible to recover. However, I consider my approach superior because I can guarantee that for every successfully completed entry action there will always be a matching call to the exit action. You cannot give such a guarantee.
If this is needed only rarely I'd rather have users work around the problem by setting a boolean and posting an error event in a failing exit action and then testing that boolean in all following exit actions.
Eeeeew, that's gross. Sorry, but that just smells like an awful hack.
I very much agree. But don't we have to do the same when we want to signal a destructor failure?
Why not just call the state object's exit() member function if it has one?
That might be a solution but I'd rather avoid this complication as long as there are no concrete use-cases for it. Regards, Andreas