In digging into a problem with Protocols.HTTP.Promise, I came across an issue with inheritance and destructors.
#ifdef HTTP_PROMISE_DESTRUCT_DEBUG # define PROMISE_DESTRUCTOR \ protected void _destruct() { \ werror("%O()._destruct()\n", object_program(this)); \ } #else # define PROMISE_DESTRUCTOR #endif
Activating this debug flag actually prevents the parent destructors from being called. And simply adding ::_destruct() into there doesn't work either, as that will break for anything that DOESN'T have a _destruct in its parent.
How can this be solved generically? The symbol ::_destruct simply can't be looked up (at compile time) if the parent doesn't have one.
ChrisA
Chris Angelico wrote:
In digging into a problem with Protocols.HTTP.Promise, I came across
# define PROMISE_DESTRUCTOR \ protected void _destruct() { \ werror("%O()._destruct()\n", object_program(this)); \
Even though I rewrote that implementation, I didn't touch (nor use) this construct.
How can this be solved generically? The symbol ::_destruct simply can't be looked up (at compile time) if the parent doesn't have one.
I think the same problem exists for constructors. Pike lacks a generic solution for both problems so far (AFAIK).
On Tue, Aug 27, 2019 at 3:18 AM Stephen R. van den Berg srb@cuci.nl wrote:
Chris Angelico wrote:
In digging into a problem with Protocols.HTTP.Promise, I came across
# define PROMISE_DESTRUCTOR \ protected void _destruct() { \ werror("%O()._destruct()\n", object_program(this)); \
Even though I rewrote that implementation, I didn't touch (nor use) this construct.
How can this be solved generically? The symbol ::_destruct simply can't be looked up (at compile time) if the parent doesn't have one.
I think the same problem exists for constructors. Pike lacks a generic solution for both problems so far (AFAIK).
With run-time lookups, you can check first:
if (obj->method) obj->method();
But this doesn't work with :: syntax because it's resolved at compile time.
I've never had this exact problem with constructors, but there's a different oddity: if you inherit from two functions that both have constructors, you need to explicitly pass the call on:
class X { inherit Y; inherit Z; protected void create() {::create();} }
Otherwise, only one of them will be called.
Changing the constructor situation would probably break a fair bit of code out there, but maybe something can be done about destructors.
ChrisA
pike-devel@lists.lysator.liu.se