[statechart] Problems if I make dtorS virtual?

When compiling the examples (statechart library downloaded from sf 18 Aug), I get the following warnings: <warnings format=edited> /usr/local/boost_1_33_0/boost/statechart/detail/state_base.hpp: In instantiation of `boost::statechart::detail::state_base<std::allocator<void>, boost::statechart::detail::rtti_policy>': /usr/local/boost_1_33_0/boost/statechart/state_machine.hpp:443: instantiated from `boost::statechart::state_machine<Machine, Greeting, std::allocator<void>, boost::statechart::null_exception_translator>' ../main.cpp:12: instantiated from here /usr/local/boost_1_33_0/boost/statechart/detail/state_base.hpp:74: warning: `class boost::statechart::detail::state_base<std::allocator<void>, boost::statechart::detail::rtti_policy>' has virtual functions but non-virtual destructor [snip] /usr/local/boost_1_33_0/boost/statechart/simple_state.hpp:189: instantiated from `boost::statechart::simple_state<Greeting, Machine, boost::mpl::list<mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na,mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, has_no_history>' ../main.cpp:14: instantiated from here /usr/local/boost_1_33_0/boost/statechart/detail/leaf_state.hpp:27: warning: `class boost::statechart::detail::leaf_state<std::allocator<void>, boost::statechart::detail::rtti_policy>' has virtual functions but non-virtual destructor </warnings> I changed ~simple_State() and ~state_base() to virtual and the warnings disappeared. However, ~state_base() contains the following annotation: // This destructor is not virtual for performance reasons. The library // ensures that a state object is never deleted through a state_base // pointer but only through a pointer to the most-derived type. ~state_base() {} As a quick, not-definitive check, I built PingPong* with both the virtual and non-virtual dtorS using gcc 3.4.2 on an old i386-redhat-linux machine. The results appear to be the reverse of what I would expect, but I checked to verify that I have the correct result/config correspendence. ..................non-virtual.....virtual PingPongSingle.... 4.08 ..... 3.71 PingPongMulti1.... 6.01997 ..... 5.85999 PingPongMulti2.... 19.53 ..... 19.55 Reminds me of the old joke: "I see fine. I just don't understand what I'm looking at." Two questions: 1) will making the dtorS virtual lead to adverse consequences I simply haven't encountered yet; and 2) can someone help me understand what I did wrong in setting up this test? <extra_credit ot=true my_understanding=faulty> With a well-developed pipelined architecture and a reasonably rich set of addressing operations, shouldn't there be little or no difference between direct and indirect access times - given that the bookeeping normally associated with virtual classes has already been paid for? </extra_credit> Thanks to any/all for help with this. Regards, Dick Bridges "Multithreading is just one damn thing after, before, or simultaneous with another." Scott Meyers and Andrei Alexandrescu

Hi Dick BRIDGES Dick wrote:
When compiling the examples (statechart library downloaded from sf 18 Aug), I get the following warnings:
[snip warnings]
I changed ~simple_State() and ~state_base() to virtual and the warnings disappeared. However, ~state_base() contains the following annotation:
// This destructor is not virtual for performance reasons. The library // ensures that a state object is never deleted through a state_base // pointer but only through a pointer to the most-derived type. ~state_base() {}
As a quick, not-definitive check, I built PingPong* with both the virtual and non-virtual dtorS using gcc 3.4.2 on an old i386-redhat-linux machine.
I would expect the PingPong examples to deliver the least-dependable information regarding virtual vs. non-virtual dtors. This is due to the fact that a lot of stuff is going on besides the destruction of states. I think BitMachine would make for a better testing platform...
The results appear to be the reverse of what I would expect, but I checked to verify that I have the correct result/config correspendence.
..................non-virtual.....virtual PingPongSingle.... 4.08 ..... 3.71 PingPongMulti1.... 6.01997 ..... 5.85999 PingPongMulti2.... 19.53 ..... 19.55
Hmmm, here's what I get on a 3.2GHz Intel Pentium 4 Windows XP machine (all numbers in microseconds non-virtual / virtual): *** MSVC7.1 *** PingPongSingle: 1.06 / 1.07 PingPongMulti1: 5.41 / 5.43 PingPongMulti2: 12.34 / 12.26 BitMachineCustom3: 0.18 / 0.19 *** GCC 3.4.2 (MinGW) *** PingPongSingle: 1.27 / 1.27 PingPongMulti1: 6.03 / 6.11 PingPongMulti2: 13.20 / 13.27 BitMachineCustom3: 0.32 / 0.30 *** Intel 9.0 *** PingPongSingle: 1.14 / 1.14 PingPongMulti1: 5.38 / 5.43 PingPongMulti2: 12.27 / 12.35 BitMachineCustom3: 0.16 / 0.16 I.e. no significant difference non-virtual vs. virtual. Two things come to mind: 1. At the point where states are destructed (see simple_state.hpp, line 983) the compiler might know that the type of the pointer matches the runtime type of the referenced object and therefore call the virtual destructor non-virtually. However, I'm not sure whether such compiler magic is implemented in any of the tested platforms nor do I have a clue whether that's possible at all (it does sound pretty impossible) 2. There could be little difference on modern processors anyway (as you have mentioned)
Reminds me of the old joke: "I see fine. I just don't understand what I'm looking at." Two questions: 1) will making the dtorS virtual lead to adverse consequences I simply haven't encountered yet;
Given the numbers above I don't see any problems whatsoever. Not on the tested processors, that is. I can't say whether the picture is the same for processors used in the embedded world.
and 2) can someone help me understand what I did wrong in setting up this test?
Difficult to say. Could you build with bjam and repeat the test?
<extra_credit ot=true my_understanding=faulty>
:-), my understanding is non-existent in this area...
With a well-developed pipelined architecture and a reasonably rich set of addressing operations, shouldn't there be little or no difference between direct and indirect access times - given that the bookeeping normally associated with virtual classes has already been paid for? </extra_credit>
I think my numbers make some limited sense. I don't see how the virtual dtor version could actually be faster as your numbers suggest. Regards, -- Andreas Huber When replying by private email, please remove the words spam and trap from the address shown in the header.

On Wed, 24 Aug 2005 11:16:10 -0700, BRIDGES Dick wrote
<extra_credit ot=true my_understanding=faulty> With a well-developed pipelined architecture and a reasonably rich set of addressing operations, shouldn't there be little or no difference between direct and indirect access times - given that the bookeeping normally associated with virtual classes has already been paid for? </extra_credit>
Thanks to any/all for help with this.
The problem with virtual functions is that they expand the size of the object in memory (sometimes dramatically) and will prevent the objects from being used in shared memory. These issues might not be a priority for statecharts, but that's a call the users and Andreas will have to make. Jeff
participants (3)
-
Andreas Huber
-
BRIDGES Dick
-
Jeff Garland