X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Finclude%2Fsmobs.hh;h=0d446102e19b0b042b5fac463f206427777898ea;hb=0943e805fa82ebeb1d1ed32e675070467e340c39;hp=7ef46b23e41106eb444907d665cd1a6aecac80c8;hpb=855e8e36a0c75aa75076fabe19aa292a6902ec96;p=lilypond.git diff --git a/lily/include/smobs.hh b/lily/include/smobs.hh index 7ef46b23e4..0d446102e1 100644 --- a/lily/include/smobs.hh +++ b/lily/include/smobs.hh @@ -320,6 +320,32 @@ public: } }; +// This is a tricky thing: once a base class calls smobify_self () in +// its constructor, further allocations during construction of base +// class and derived classes might lead to mark_smob calls on the +// object under construction. When those call a virtual function like +// derived_mark, the virtual function corresponding to the +// incompletely initialized object is likely to be called. +// +// The order of initialization of an object consists in calling the +// constructors of virtual base classes, then of non-virtual base +// classes, then initializing all data members. +// +// As a result, the derived constructor comes too late for +// initialization. That's where the Preinit template class comes in. +// Derive from it _before_ deriving from the smobifying base class +// providing derived_mark, and it will call its Base class' pre_init +// function (which must not rely on the instantiation being complete). + +template +class Preinit { +protected: + Preinit () + { + (static_cast (this)) -> pre_init (); + } +}; + extern bool parsed_objects_should_be_dead; class parsed_dead {