Archived

This forum has been archived. Please start a new discussion on GitHub.

"no unique final overrider" appears in 3.0.1-3.4.1 move

Hi.

I'm trying to move some C++ projects on RHEL 5 (GCC 4.1.2) from Ice 3.0.1 to Ice 3.4.1. We have slice/C++ interface/class hierarchies that compiled fine with 3.0.1 but break on 3.4.1, and I'm trying to figure out why.

The errors I'm getting say things like this:

"SegCertify.h:22: error: no unique final overrider for `virtual const std::string& SPData::BaseSegIF::ice_id(const Ice::Current&) cons' in `SegCertify'."

I'm no C++ expert, but it seems like maybe we have the problem described here:

http://www.zeroc.com/forums/help-center/4869-implementing-multiple-interfaces-single-c-class.html

What strikes me as odd is the fact that this problem suddenly appeared with Ice 3.4.1. Does that seem seem possible, Ice developers, or do I have some other build problem?

Comments

  • Oh. I was able to make this error go away by editing the generated .h file for my project. Our C++ class, SegCertify.h, inherits from a Slice-generated type called PersistentPsuCert, which inherits virtually from an Ice interface but non-virtually from an Ice class. I changed it to virtual inheritance from the class, and everything was better. But I don't really understand what I've done or why slice2cpp is doing what it's doing. Sorry for the clumsy descriptions. I'll try to work up a minimal example.
  • bernard
    bernard Jupiter, FL
    Hi Andrew,

    It would be helpful to include the declaration of your class, together with the Slice definitions of the interfaces (classes, structs...) it refers to.

    This error would indeed occur if you're implementing directly multiple generated classes. It's surprising but not impossible that this code compiled with 3.0.1.

    Cheers,
    Bernard
  • bernard
    bernard Jupiter, FL
    If you're using a complex inheritance hierarchy, with multiple inheritance from abstract classes generated from Slice interfaces and classes, my first recommendation is: refactor and simplify your code!

    Then, if you really like multiple inheritance and know what you're doing, have a look at the "cpp:virtual" metadata in http://www.zeroc.com/doc/Ice-3.4.1-IceTouch/manual/Metadata.48.3.html. This could explain the difference you're seeing between Ice 3.0.1 and Ice 3.4.1, as this "cpp:virtual" used to be the default.

    Cheers,
    Bernard
  • Sounds like some good advice. This is not my code; I'm just the lucky guy in charge of our 3.4.1 upgrade. (I mostly work on our client apps, which are C#, my "first" language.) Thanks for the pointer on the cpp:virtual directive. I think I'll try that for now and leave the refactoring to people more familiar with the code.
  • So I've applied ["cpp:virtual"] to the Ice classes from which we derive our servants. The slice definition for one such class looks like this:
    ["cpp:virtual"] class PersistentBasePsu implements BaseSegIF {
      // fields and methods
    };
    

    slice2cpp produces this:
    class PersistentPsu : virtual public ::SPData::PersistentBasePsu,
                          virtual public ::SPData::SegmentIF, private IceInternal::GCShared
    {
     // fields and methods
    };
    

    I'm curious why the IceInternal::GCShared is private and non-virtual. I ask, not because I know enough to expect otherwise, but because I can get rid of a build error by making it public and virtual. Here's the error:
    /network/Ice-3.4.1/include/Ice/GCShared.h: In destructor ‘IceUtil::Handle<T>::~Handle() [with T = Segment]’:
    Initializer.cc:17: instantiated from here
    /network/Ice-3.4.1/include/Ice/GCShared.h:34: error: ‘virtual void IceInternal::GCShared::__decRef()’ is inaccessible
    /network/Ice-3.4.1/include/IceUtil/Handle.h:197: error: within this context
    /network/Ice-3.4.1/include/IceUtil/Handle.h:197: error: ‘IceInternal::GCShared’ is not an accessible base of ‘Segment’

    Sorry for asking reverse-engineered questions; I'm just stuck and hoping for another insight like ["cpp:virtual"].