[Not a bug] Mixins + Inheritance

Bugs that have been investigated and resolved somehow.

Moderator: GZDoom Developers

Forum rules
Please don't bump threads here if you have a problem - it will often be forgotten about if you do. Instead, make a new thread here.

Mixins + Inheritance

Postby 4page » Sat Feb 12, 2022 9:09 am

Not sure if this is a bug or not. When using a mixin on a class which also inherits from a different class I realized they both (the mixin and the parent class) had a function with the same name. The game ran fine, and when I checked it seemed that it was running the mixin version of the function. I was told this might be a bug and to make an example to post here, but when I made the example it would only run the parent class function. And if there are 2 mixins that have the same function as the parent class then the game won't run as it sees the duplicate between the parent and the 2nd mixin, but not the first.

Spawn the Test_Child class, or uncomment the Test_Mixin2 line to see.

Code: Select allExpand view
Mixin Class Test_Mixin1
{
   void Test_Function()
   {
      console.printf(string.format("This is the mixin #1"));
   }
}

Class Test_Parent : ACTOR
{
   void Test_Function()
   {
      console.printf(string.format("This is the Parent Actor"));
   }
   Default
   {
      +NOINTERACTION;
   }
   States
   {
      Spawn:
         TNT1 A 0 Nodelay Test_Function();
         Stop;
   }
}

Mixin Class Test_Mixin2
{
   void Test_Function()
   {
      console.printf(string.format("This is the mixin #2"));
   }
}

Class Test_Child : Test_Parent
{
   Mixin Test_Mixin1;
   //Mixin Test_Mixin2;
}
User avatar
4page
 
Joined: 06 Aug 2019
Location: American Pacific Northwest
Discord: 4page#3223

Re: Mixins + Inheritance

Postby Graf Zahl » Mon Apr 04, 2022 5:22 am

This behaves as would be expected. The mixin function takes priority due to how mixins are handled by the compiler.
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
 
Joined: 19 Jul 2003
Location: Germany

Re: Mixins + Inheritance

Postby phantombeta » Mon Apr 04, 2022 5:50 am

4page wrote:Not sure if this is a bug or not. When using a mixin on a class which also inherits from a different class I realized they both (the mixin and the parent class) had a function with the same name. The game ran fine, and when I checked it seemed that it was running the mixin version of the function. I was told this might be a bug and to make an example to post here, but when I made the example it would only run the parent class function. And if there are 2 mixins that have the same function as the parent class then the game won't run as it sees the duplicate between the parent and the 2nd mixin, but not the first.

This is indeed not a bug, and it's not related to mixins, either.

For specifics on what's going on here: This is called function hijacking, or shadowing¹. ZScript² allows you to define a new non-virtual function with the same name as one in a base class. However, since it's not virtual³, the only way for the compiler to know it exists is if the variable or expression is typed as the type that shadows the function or one of its descendants.
The reason it can still call the "correct" function when typed as the shadowing type is because the compiler first searches for the symbol⁴ in the class' own list of symbols - if not found, it then looks for it in the parent's list, then the parent's parent's list, and so on. Since the class' own list is searched first, the function that's doing the shadowing is also the one that's found first.

Code: Select allExpand view
class Foo {
    void SomeFunction () { /* [...] */ }
}

class Bar : Foo {
    // This shadows the original SomeFunction defined in "Foo"
    void SomeFunction () { /* [...] */ }
}

class Baz {
    void A () {
        Foo a = new ("Foo");
        Bar b = new ("Bar");
        Foo c = bar;

        a.SomeFunction (); // This will call Foo's SomeFunction
        b.SomeFunction (); // This will call Bar's SomeFunction
        c.SomeFunction (); // This will call Foo's SomeFunction
    }
}



¹: Also known as "symbol⁴ hijacking" or "symbol shadowing" in the general case.
²: And many other languages too. However, as far as I know nowadays it's not too common in new languages, because it only leads to bugs - there's not really any situation in which it won't cause needless confusion.
³: This is because virtual functions work differently than non-virtual ones - it chooses the function that needs to be called entirely at runtime, usually through something called a vtable, which is a list containing pointers to all the virtual functions of the type.
⁴: This is a term used to refer to the names of things like variables, functions, classes, etc.
User avatar
phantombeta
Tired of being treated like trash by control freaks
 
Joined: 02 May 2013


Return to Closed Bugs

Who is online

Users browsing this forum: No registered users and 0 guests