Menu

#932 'using' directive may prevent constructor wrapping

None
closed
5
2023-08-05
2008-06-19
No

Hi SWIG developers,

The problem is related to bringing inherited pure virtual methods into a class scope by means of using directive and is easy to reproduce.

Given a base class:

class Base
{
public:
virtual void f(int n) = 0;
void f(double another_representation_of_n)
{
f(some_conversion(another_representation_of_n);
}
};

And a derived class

class Derived
{
public:
Derived(...) {}

using Base::f;
virtual void f(int n) {...}
};

The constructor for Derived won't be wrapped. The inclusion of void f(int) into Derived scopes makes SWIG think that the class is abstract. However this use of using is pretty much justified, not doing it will make f(int) unaccessible from Derived and we don't want to override that function just to 'call super'.

I can workaround this with a #ifndef SWIG for the using directive but, for a Java wrapping, the generated interface is not exactly the same since the overloaded version of f doesn't appear in the derived class. Hence, as I'm not sure if the scope resolution in Java is the same as in C++, I don't know f the workaround is completely correct.

The safest approach would be rewrapping methods in the derived class (as SWIG is actually doing) but the constructors mustn't be removed.

Thanks and best regards,
Juan

Discussion

  • William Fulton

    William Fulton - 2008-06-21

    Logged In: YES
    user_id=242951
    Originator: NO

    Workaround is to swap the following lines:
    using Base::f;
    virtual void f(int n) {...}

    so the using statement is after the f(int n) declaration.

    For future reference when someone has time to look at this bug, the problem is probably somewhere in Swig_symbol_clookup_local_check (called from Allocate::is_abstract_inherit) to do with the code in the

    while (s && Checkattr(s, "nodeType", "using"))

    loop and the call to check_implemented.

     
  • Juan Hernando

    Juan Hernando - 2008-06-26

    Logged In: YES
    user_id=2048274
    Originator: YES

    Thanks for your fast reply and workaround.
    Best Regards,
    Juan

     
  • William Fulton

    William Fulton - 2009-11-14

    Your code above is invalid. However, if it is corrected:

    %inline %{
    class Base
    {
    public:
      virtual void f(int n) = 0;
      void f(double another_representation_of_n)
      {
      }
    };
    
    //And a derived class
    
    class Derived : public Base
    {
    public:
      Derived() {}
    
      using Base::f;
      virtual void f(int n) {}
    };
    %}
    

    Then Derived does not have a constructor and this is incorrect. There is an easy workaround for now and that is to swap two lines around as such:

    virtual void f(int n) {}
    using Base::f;
    
     

    Last edit: William Fulton 2023-07-29
  • Olly Betts

    Olly Betts - 2022-03-16

    Reproduced using William's testcase and -python -c++ with SWIG git master.

     
  • William Fulton

    William Fulton - 2023-08-05
    • status: open --> closed
    • assigned_to: William Fulton
    • Group: -->
     
  • William Fulton

    William Fulton - 2023-08-05

    Fixed in 93732bb19562534c81c537b8a83e38451556415c for swig-4.2.0.

     

Log in to post a comment.