Boost logo

Boost Users :

Subject: [Boost-users] [MSM] Solution for: fatal error C1202: recursive type or function dependency context too complex RE-POST
From: Mark Bartosik (mbartosik_at_[hidden])
Date: 2015-10-21 20:09:25


Sorry this is a re-post because my email client had formatting enabled.

I have had a major headache while using MSM eUML state transition tables, thankfully I've found a simple solution.
First MSM and especially eUML are great, and that's why I persevered to find a solution.

Here's the problem:

Declaring a complex eUML state transition table may result in the compiler generating an error.

BOOST_MSM_EUML_DECLARE_TRANSITION_TABLE((
// row_1,
// row_2,
// ...
// row_a,
// row_b,
// row_c,
//
// Eventually the Microsoft compiler VS2008,2010,2012,2015 will all explode with fatal C1202: recursive type or function dependency context too complex
), transition_table );

I haven't tried with gcc.

The solution is to break the state table in two smaller parts rather than one big table:

BOOST_MSM_EUML_DECLARE_TRANSITION_TABLE((
// row_1,
// row_2,
// ...
), transition_table_part_1 );

BOOST_MSM_EUML_DECLARE_TRANSITION_TABLE((
// row_a,
// row_b,
// row_c
), transition_table_part_2 );

typedef boost::mpl::joint_view< transition_table_part_1, transition_table_part_2 > transition_table; // No error, even though it contains just as many rows

[Waffle warning] I think that what's happening is that once the compiler has fully described the transition_table_part1 it unwinds what it is doing, it is able to unwind and 'bank' transition_table_part1 as just being a type in it's memory, and when it comes to generate transition_table via boost::mpl::join_view it just constructing the resulting type list from two sets of previously 'banked' types. This is I think why I can still nest a sub-state machine which is on the limit of the complexity of state transition table it can contain; even though nesting state machines recursively references state transition tables.

Things that did not work: [ more waffle ] There are some other solutions that I tried before I had the Eureka moment. One was to try to hide a sub-state machine within a concrete class but that didn't work because the outer fsm needs to see the inner stt. Another way was to implement a sub-state machine as a concrete state (not fsm), and then add a process_event method on the class which delegated to a member fsm which was hidden from the outer fsm, I got this to work, but it did not solve the problem, and I had to abandon use of exit_pt_, although it may have brought down compile times.

Another helpful advantage of this solution is that the memory required by the compiler is significantly reduced.

Christophe:
Would you consider adding the example above to the MSM documentation, I would suggest under:
Chapter 4, Compilers / Performance, Compilers Corner

Also under:
Chapter 5, Questions Answers and Tips:

Question: Why do I get "fatal C1202: recursive type or function dependency context too complex"
Answer: Likely because a state transition table has become two complex. Split the state transition table into two parts, and then use typedef mpl::joint_view< transition_table_part_1, transition_table_part_2 > transition_table to join the two parts.

Question: Why does my compiler generate a fatal out of memory fatal error.
Answer: Likely because a state transition table has become two complex. Try and split the most complex state transition table into two parts, and then use typedef mpl::joint_view< transition_table_part_1, transition_table_part_2 > transition_table to join the two parts.

- Mark Bartosik


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net