Modify

Ticket #3730 (closed Bugs: wontfix)

Opened 4 years ago

Last modified 3 years ago

compilation problem with is_virtual_base_of when class contains abstract methods

Reported by: Barry Searle <barry.searle@…> Owned by: johnmaddock
Milestone: Boost 1.42.0 Component: type_traits
Version: Boost 1.41.0 Severity: Problem
Keywords: Cc: manfred.doudar@…

Description

When a virtual base class contains an abstract method that is implemented in the inheritance tree, rather than the final class, gcc won't compile serialized classes. This happens with gcc 4.3.1 on openSuSE 11.0 and gcc 4.4.1 on 11.2.

I'm attaching a modified version of the test_diamond.cpp program from the serialization library. The base class now contains an abstract method, the final class in the example has been renamed to intermediate and a new final class is derived directly from intermediate. The abstract method is implemented in the intermediate class resulting in a compiler error
/usr/local/boost-r58233/include/boost/type_traits/is_virtual_base_of.hpp:56: error: no unique final overrider for ‘virtual void base::method1()’ in ‘boost::detail::is_virtual_base_of_impl<intermediate, final, mpl_::bool_<true> >::X’
The method looks to be unique to me. If the method is implemented in final rather than intermediate then the problem doesn't occur.

Attachments

test_diamond2.cpp Download (6.4 KB) - added by Barry Searle <barry.searle@…> 4 years ago.
example program to reproduce problem

Change History

Changed 4 years ago by Barry Searle <barry.searle@…>

example program to reproduce problem

comment:1 Changed 4 years ago by johnmaddock

I can't at present see a way to fix this, here's a reduced test case:

#include <map>
#include <iostream>
#include <boost/type_traits.hpp>

class base {
public:
    base() : i(0) {}
    base(int i) : i(i)
    {
        m[i] = "text";
    }

    virtual void method1() = 0;

    virtual ~base() {};
private:
    int i;
    std::map<int, std::string> m;    
};

class derived1 : virtual public base {
public:
};

class derived2 : virtual public base {
public:    
};

class intermediate : public derived1, public derived2 {
public:
    intermediate() {}
    intermediate(int i) : base(i) {}

    void method1();
};

void intermediate::method1()
{
}

class final : public intermediate {
public:
    final() {}
    final(int i) : base(i) {}
};

//
// This class demonstrates what we need to make work inside is_virtual_base_of.
// MSVC compiles this just fine (likewise is_virtual_base_of), and only complains
// when attempting to use method1.  Other compilers (GCC, Intel on Linux) complain
// as soon as X is declared, likewise when instantiating is_virtual_base_of.
//
struct X : final, virtual intermediate 
{
 X();
 X(const X&);
 X& operator=(const X&);
 ~X()throw();
};

int main( int /* argc */, char* /* argv */[] )
{
   X x;
   x.method1();
   boost::is_virtual_base_of<intermediate, final>::type t;
   return t.value != true;
}

comment:2 Changed 4 years ago by manfred.doudar@…

  • Cc manfred.doudar@… added

Since Final inherits from Intermediate, and X from both - you in effect have a "diamond" since X can take a path either through Final or Intermediate. In which case:

class final : public virtual intermediate

should resolve matters, no?

comment:3 Changed 3 years ago by johnmaddock

  • Status changed from new to closed
  • Resolution set to wontfix

Class Final is defined outside our control - that's the issue - I'm closing this as "unfixable" for now.

comment:4 Changed 3 years ago by barry.searle@…

What happens next? will it be removed from release versions of the library? or modified so it at least compiles?

comment:5 Changed 3 years ago by anonymous

Nothing happens next - unless someone can come up with a fix - as far as anyone can tell it's simply not possible to make the trait work in every possible case like this - since the trait isn't part of the next std the only solution for occational difficult cases like this, is for the user to supply a specialisation of is_virtual_base_of.

HTH, John.

comment:6 Changed 3 years ago by johnmaddock

(In [67912]) Document the restrictions on is_virtual_base_of. Refs #3730.

comment:7 Changed 3 years ago by johnmaddock

(In [67913]) Document the restrictions on is_virtual_base_of. Refs #3730.

comment:8 Changed 3 years ago by johnmaddock

(In [67916]) Document the restrictions on is_virtual_base_of. Refs #3730.

View

Add a comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
The resolution will be deleted. Next status will be 'reopened'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.