
Hi everyone, Hi Christophe, Using Boost.MSM with eUML I tried to access the attribute of a state from within an action. However, the value is not what I expected when accessing the attribute of the state given as argument to the action. (It seems to be the default-parameter.) If I access the state directly (by name) and retrieve the value from it, it is set correctly as expected. Could it be that an action gets its arguments as copies? If so, I guess, the attributes of the copied arguments should be copied, too. This is the case for events. The attributes of an event given to the action seems to be set correctly. But the attributes of a state seem to be default-initialized. For clarification a simple example (this time tested and successfully compiled): #include <iostream> #define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS #include <boost/msm/back/state_machine.hpp> #include <boost/msm/front/euml/euml.hpp> using namespace boost::msm::front::euml; namespace msm = boost::msm; namespace mpl = boost::mpl; using namespace std; namespace { // The attribute: BOOST_MSM_EUML_DECLARE_ATTRIBUTE(int, Number) BOOST_MSM_EUML_ATTRIBUTES((attributes_ << Number), NumberAttr) // An event containing the attribute: BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES(event1, NumberAttr) // Two states with attributes: BOOST_MSM_EUML_STATE((no_action, no_action, attributes_ << Number), state1) BOOST_MSM_EUML_STATE((no_action, no_action, attributes_ << Number), state2) // Entry-action which initializes the attributes: BOOST_MSM_EUML_ACTION(init_events_and_states) { template <class Evt, class Fsm, class State> void operator()(Evt const&, Fsm&, State&) { event1.get_attribute(Number) = 100; state1.get_attribute(Number) = 1; state2.get_attribute(Number) = 2; }; }; // Action that prints the Number-attributes of event and state. // NOTE: The state-Numbers differ! BOOST_MSM_EUML_ACTION(printNumber) { template <class Fsm, class Evt, class SourceState, class TargetState> void operator()(Evt const& evt, Fsm&, SourceState& source, TargetState& target) { std::cout << "In action \"printNumber\"." << "\n event1.Number == " << event1.get_attribute(Number) << "\n evt.Number == " << evt.get_attribute(Number) << "\n state1.Number == " << state1.get_attribute(Number) << "\n source.Number == " << source.get_attribute(Number) << "\n state2.Number == " << state2.get_attribute(Number) << "\n target.Number == " << target.get_attribute(Number) << std::endl; }; }; // The transition table: BOOST_MSM_EUML_TRANSITION_TABLE(( state1 + event1 / printNumber == state2 ), stt) // The FSM front-end and back-end: BOOST_MSM_EUML_DECLARE_STATE_MACHINE(( stt, init_ << state1, init_events_and_states ), FsmFrontend); typedef msm::back::state_machine<FsmFrontend> Fsm; void test() { Fsm fsm; // needed to start the highest-level FSM. // This initializes all attributes. fsm.start(); // emit event1 fsm.process_event(event1); } } // namespace int main() { test(); return 0; } // This prints the following (except "//") on the cmdline : // In action "printNumber". // event1.Number == 100 // evt.Number == 100 // state1.Number == 1 // source.Number == 0 // state2.Number == 2 // target.Number == 0 As you can see, the attribute-values of "event1" and "evt" are the same. However, the attribute-values of "state1" and "source" differ although they should be the same, too. (The same applies to "state2" and "target".) I tried this example with a custom type as attribute-type which prints each constructor-call and assignment-call and I realized, the copy-constructor was never called. If you want to try it yourself, just replace the declaration of the attribute in the above example with the following code: class MyInt { int val_; public: MyInt() : val_(50) { std::cout << "MyInt()" << std::endl; } MyInt(const MyInt& obj) : val_(obj.val_) { std::cout << "MyInt(const MyInt&) - val_=" << val_ << std::endl; } MyInt(const int& i) : val_(i) { std::cout << "MyInt(const int&) - val_=" << val_ << std::endl; } MyInt& operator=(const MyInt& obj) { val_ = obj.val_; std::cout << "op=(const MyInt&) - val_=" << val_ << std::endl; return *this; } MyInt& operator=(const int& i) { val_ = i; std::cout << "op=(const int&) - val_=" << val_ << std::endl; return *this; } }; // The attribute: BOOST_MSM_EUML_DECLARE_ATTRIBUTE(MyInt, Number) This looks like a bug, but I am not sure. Maybe I have to write my transition-table differently? Ciao, Deniz PS: I am using Boost 1.53.0 with GCC 4.7.2 (and C++11 support activated, most of the time.)