Jean Abou Samra <[email protected]> writes: > For example, if I were the author of the below code, how > would I understand that the mmrest_event_ should be > unprotected? > > void > Part_combine_iterator::kill_mmrest (Context *c) > { > if (!mmrest_event_) > { > mmrest_event_ = new Stream_event > (Lily::ly_make_event_class (ly_symbol2scm ("multi-measure-rest-event"))); > set_property (mmrest_event_, "duration", SCM_EOL); > mmrest_event_->unprotect (); > } > > c->event_source ()->broadcast (mmrest_event_); > }
Uh, after the call to mmrest_event_->unprotect () there is nothing that would protect the newly created mmrest_event_ . This is just hoping that the first of the functions that this broadcast to will protect it before any allocation occurs. In short, yes, this is potentially a bad Heisenbug. The proper way would be to unprotect after the broadcast call, or to convert mmrest_event_ to an SCM value and do an scm_remember_upto_here_1 call on it after the broadcast. A better interface would have been to let broadcast take an SCM value: that way it can keep the SCM value alive until it doesn't need it anymore and the caller does not need to keep it live in some contorted manner. -- David Kastrup
