Repository navigation
Problems with reentering a terminated substate. #440
Copy link
Copy link
Closed
Description
Hey there!
We encountered the following issue:
Expected Behavior
Having a look at the following code snippet, we expect that the SubSubState is at Leave3 after trying to enter it for the second time.
Actual Behavior
When we try to reenter SubSubState in SubState for the second time (after leaving it), it stucks at the termination state X.
Steps to Reproduce the Problem
#include <boost/sml.hpp>
#include <cassert>
#include <deque>
#include <iostream>
#include <queue>
namespace sml = boost::sml;
namespace {
struct event_1 {};
struct event_2 {};
struct event_3 {};
struct event_4 {};
struct Leave1 {};
struct Leave2 {};
struct Leave3 {};
struct SubSubState {
auto operator()() const noexcept {
using namespace sml;
return make_transition_table(*state<Leave3> + event<event_4> / process(event_3{}) = X);
}
};
struct SubState {
auto operator()() const noexcept {
using namespace sml;
return make_transition_table(*state<SubSubState> + event<event_3> / process(event_2{}) = X);
}
};
struct StateMachine {
auto operator()() const noexcept {
using namespace sml;
return make_transition_table(*state<Leave1> + event<event_1> = state<SubState>,
state<SubState> + event<event_2> = state<Leave1>);
}
};
} // namespace
int main(int argv, char** argc) {
sml::sm<StateMachine, sml::defer_queue<std::deque>, sml::process_queue<std::queue>> stm;
using namespace sml;
stm.process_event(event_1{});
assert(stm.is<decltype(state<SubState>)>(state<SubSubState>));
assert(stm.is<decltype(state<SubSubState>)>(state<Leave3>));
stm.process_event(event_4{});
stm.process_event(event_1{});
assert(stm.is<decltype(state<SubState>)>(state<SubSubState>));
assert(stm.is<decltype(state<SubSubState>)>(state<Leave3>));
}
This will output:
int main(int, char**): Assertion `stm.is<decltype(state<SubSubState>)>(state<Leave3>)' failed.
So the last assertion fails.
Specifications
Version: master
OS: Ubuntu 18.04
Compiler: gcc-10, g++-10
Acutally we found the following workaround which solves this issue:
When we change struct SubState{...} to
struct SubState {
auto operator()() const noexcept {
using namespace sml;
return make_transition_table(*state<Leave2> + sml::on_entry<_> / process(event_5{}),
state<Leave2> + event<event_5> = state<SubSubState>,
state<SubSubState> + event<event_3> / process(event_2{}) = X);
}
};
the last assertion does not fail anymore and SubSubState is a Leave_3 which is the desired behavior.
The question is why isn't it working without this workaround.
Thanks for your support.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
SchmadenSchmuki commentedon Jan 21, 2024
The same here (using the same workaround).
Took me some additional time to understand it, maybe you already know this but my explanation is:
SubStateis set toSubSubState,) but this is not performed recursively. The state ofSubState's initial stateSubSubStateis not set.SubSubStateis entered, it get its initial state set the same waySubStategets it set when it is reentered.(In my case
SubSubStatehad three states and remained/was in the state it was left in whenSubStatewas left. WhenSubStatewas reentered thenSubSubStatecould also have the middle state.)SubStateis entered because thereSubSubStateis unchanged and has the expected initial state.I think it's a bug or at least undesireable because this way
SubStatebehaves differently between the first and the following times it's entered.Until now I only used SML and didn't look into the source code, so I have no idea how difficult it would be to fix this.
In my opinion fixing it would be an improvement because to me this was unexpected behaviour and took some time to figure out. Also eliminating the workaround would simplify my state machines.
jefftrull commentedon Oct 13, 2025
Can you see if #649 helps?
SchmadenSchmuki commentedon Nov 2, 2025
Works for me, don't have the mentioned problems anymore, awesome
PavelGuzenfeld commentedon Oct 13, 2026
Fixed by #649, the second entry starts at the initial substate on master 4970fef. Can be closed.
PavelGuzenfeld commentedon Oct 17, 2026
@kris-jusiak can you close this? Fixed or answered, see the comment above.