X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Finclude%2Fsmobs.hh;h=00217866dc07dc92eff400e23050d50b46f67a3b;hb=6786ba7b5cd73f94eec0a49fd68d0e6d9d283437;hp=0d446102e19b0b042b5fac463f206427777898ea;hpb=ca2a46da10e1f627b68e7243958749b8ec007f43;p=lilypond.git diff --git a/lily/include/smobs.hh b/lily/include/smobs.hh index 0d446102e1..00217866dc 100644 --- a/lily/include/smobs.hh +++ b/lily/include/smobs.hh @@ -95,6 +95,30 @@ Complex smobs are created by deriving from Smob. + However, this is not sufficient when classes with their own + protectable elements are derived from the Complex base class. This + is because initialization order 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 of derived + class type 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 constructor of a derived class comes too late for + initialization of data members that may be accessed in the + derived_mark kind of functions. + + Such data members are consequently moved into Preinit_* classes + which come before the smobifying base class in derivation order and + construct the contained data members in a state suitable for + derived_mark calls. + + CALLING INTERFACE Common global functions for accessing C++ smob objects: @@ -320,32 +344,6 @@ 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 {