...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
Compilers are sometimes full of surprises and such strange errors happened in the course of the development that I wanted to list the most fun for readers’ entertainment.
VC8:
template <class StateType> typename ::boost::enable_if< typename ::boost::mpl::and_< typename ::boost::mpl::not_< typename has_exit_pseudo_states<StateType>::type >::type, typename ::boost::mpl::not_< typename is_pseudo_exit<StateType>::type >::type >::type, BaseState*>::type
I get the following error:
error C2770: invalid explicit template argument(s) for '`global namespace'::boost::enable_if<...>::...'
If I now remove the first “::” in ::boost::mpl , the compiler shuts up. So in this case, it is not possible to follow Boost’s guidelines.
VC9:
This one is my all times’ favorite. Do you know why the exit pseudo states are referenced in the transition table with a “submachine::exit_pt” ? Because “exit” will crash the compiler. “Exit” is not possible either because it will crash the compiler on one machine, but not on another (the compiler was installed from the same disk).
Sometimes, removing a policy crashes the compiler, so some versions are defining a dummy policy called WorkaroundVC9.
Typeof: While g++ and VC9 compile “standard” state machines in comparable times, Typeof (while in both ways natively supported) seems to behave in a quadratic complexity with VC9 and VC10.
eUML: in case of a compiler crash, changing the order of state definitions (first states without entry or exit) sometimes solves the problem.
g++ 4.x: Boring compiler, almost all is working almost as expected. Being not a language lawyer I am unsure about the following “Typeof problem”. VC9 and g++ disagree on the question if you can derive from the BOOST_TYPEOF generated type without first defining a typedef. I will be thankful for an answer on this. I only found two ways to break the compiler:
Add more eUML constructs until something explodes (especially with g++-4.4)
The build_terminate function uses 2 mpl::push_back instead of mpl::insert_range because g++ would not accept insert_range.
You can test your compiler’s decltype implementation with the following stress test and reactivate the commented-out code until the compiler crashes.