Opened 13 years ago

Closed 12 years ago

Last modified 12 years ago

#3730 closed Bugs (wontfix)

compilation problem with is_virtual_base_of when class contains abstract methods

Reported by: Barry Searle <barry.searle@…> Owned by: John Maddock
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 (1)

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

Download all attachments as: .zip

Change History (9)

by Barry Searle <barry.searle@…>, 13 years ago

Attachment: test_diamond2.cpp added

example program to reproduce problem

comment:1 by John Maddock, 13 years ago

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 by manfred.doudar@…, 13 years ago

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 by John Maddock, 12 years ago

Resolution: wontfix
Status: newclosed

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

comment:4 by barry.searle@…, 12 years ago

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

comment:5 by anonymous, 12 years ago

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 by John Maddock, 12 years ago

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

comment:7 by John Maddock, 12 years ago

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

comment:8 by John Maddock, 12 years ago

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

Note: See TracTickets for help on using tickets.