I'm having trouble with the following code:
#include "tinyfsm.hpp"
struct Event : tinyfsm::Event { };
struct State1;
struct State2;
struct Fsm : tinyfsm::Fsm<Fsm> {
virtual void react(Event const &) { }
virtual void entry() { }
void exit() { };
virtual ~Fsm() { }
};
struct State1 : Fsm{
void react(Event const & event) override { transit<State2>(); }
void entry() override { }
};
struct State2 : Fsm{
void react(Event const & event) override { transit<State1>(); }
void entry() override { }
};
FSM_INITIAL_STATE(Fsm, State1)
The compiler gives the message:
"..\src\tinyfsm.hpp", line 134: cc0513: error: a value of type "State2 *" cannot be assigned to an entity of type "Fsm *"
current_state_ptr = &_state_instance<S>::value;
^
detected during instantiation of "void tinyfsm::Fsm<F>::transit<S>() [with F=Fsm, S=State2]" at line 31 of "..\src\testbed.cpp"
I'm pretty sure this is because the compiler does not understand that State2 inherits from Fsm.
Is there any way to break the circular dependency, or give the compiler the relevant information so that it will compile correctly?
I'm using ccblkfn.exe version 8.12.0.0 (working on a blackfin processor)
I think it might be a compiler bug as this code compiles just fine on g++ 6.3.0.
The compilation error appears to be because:
This declares a
struct
namedFsm
in the global namespace.The header defines a type with the same name in the
tinyfsm
namespace. The macro callExpands to this macro declaration:
This ends up expanding to:
What do you think the
<Fsm>
part ends up refering to? Not your class, but theFsm
template in the tinyfsm namespace. Hillarity ensues.There are several simple ways to resolve this ambiguity.
The macro now inserts a reference to your
Fsm
struct in the global namespace.Another way is to simply rename your
Fsm
class to something else.A third way is to put all of your classes into their own namespace, then (outside of your namespace).