dworkin / dgd

Dworkin's Game Driver, an object-oriented database management system originally used to run MUDs.
https://www.dworkin.nl/dgd/
GNU Affero General Public License v3.0
103 stars 31 forks source link

questionable static function call binding #57

Closed shentino closed 3 years ago

shentino commented 3 years ago

Ok, so this is a weird case where which version of a function is being called appears to depend on where it is defined.

If I do:

static void status() { log("I'm the overriding function"); }

void check() { status(); }

the overriding status() gets called.

However if I do this:

void check() { status(); }

static void status() { log("I'm the overriding function"); }

Then my version of status() does NOT get called, even though it's still defined in the same program/object.

Is this what's supposed to happen or is this an anomaly?

I find it...dubious that which version of status() is actually called depends on whether I call it before or after the definition.

For further context this is showing up in kotaka's second auto, not the actual auto provided by the klib

dworkin commented 3 years ago

Working as expected.

We have discussed this before. A call to a kfun or to a static function in the auto object behaves like a ::call.

shentino commented 3 years ago

This isn't the auto object.

Not from DGD's point of view, at least.

Also the two functions I'm switching the order of are in the same program/source file.

shentino commented 3 years ago

Would it help if I provided a source file?

I'm literally only changing the order of which function is defined first in the same source, and I'm not even sure if static has anything to do with it or if auto has anything to do with it either.

dworkin commented 3 years ago
void check()
{
    status();
}

The call status(); is made to a static function in the auto object, and so it is interpreted as ::status().

shentino commented 3 years ago

Ok, so...here's my question.

If I have this:

somefile.c:

void check()
{
    status(); /* this calls status in the auto objec t*/
}

static void status() // I'm overriding status() inside somefile.c itself
{
    //this code never gets called
}

Why does it dodge my local override of status() when this does not?

somefile.c

static void status() // I'm overriding status() inside somefile.c itself, but this time defining it BEFORE defining check()
{
    //this code DOES get called
}

void check()
{
    status(); /* this calls our local status */
}

That's the part that has me confused, that while I'm defining BOTH functions locally, which version of status() is getting called literally is somehow depending on which one I define first within the same LPC source file.

shentino commented 3 years ago

My assumption was that defining it locally would intercept all local calls that weren't a ::upcall

dworkin commented 3 years ago

It is normal, expected and working as intended, and it doesn't just happen with static functions in the auto object.

Let's suppose that there is some source file obj.c which inherits from the second level auto object, i.e. the code you give in your original question.

void foo()
{
    status();
}

private void status()
{
    log("my very own status");
}

void check()
{
    status();
}

Then the status() called from foo() is in the second level auto object, and the status() called from check() is in obj.c.

shentino commented 3 years ago

Well I stand educated then!

I do appreciate the explanation.

Apparently I was under a misguided impression about how function calls were supposed to be compiled.

I thought that if you define it anywhere locally it's supposed to override every call no matter where it's invoked from.

shentino commented 3 years ago

I do have another question, separate but related.

What if you do this?

void foo()
{
    status();
}

private void status();

void check()
{
    status();
}

private void status()
{
    log("my very own status");
}

Would a forward declaration serve the same purpose as the actual definition as far as intercepting the call goes?

Also it seems I'm incapable of reopening this issue. You told me to do something like that on a separate issue and for some reason github wouldn't let me.

dworkin commented 3 years ago

Would a forward declaration serve the same purpose as the actual definition as far as intercepting the call goes?

I cannot confirm that a call is ever "intercepted," but a forward declaration to a private function does ensure that calls go to that function.

shentino commented 3 years ago

Yes that's what I meant by intercepted, apologies for the unorthodox usage.

I meant to refer to it being intercepted before it goes up the inheritance tree and hits an inherited version by default.

dworkin commented 3 years ago

Right. Except that it's not intercepted, it doesn't go up trees and there is no default.