potential GCC 5.5.0 bug?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I have a virtual and multiple inheritance situation: classes E<int> and
F<int> inherits virtually from Root<int> and G<int> 
inherits from a wrapper class MultipleInherit<Root&lt;int>,E<int>,F<int>>,
which in turns inherit from E<int> and F<int>. Here's a minimal working
example:

In testbases1.cpp:
#include<iostream>
#include<utility>
#include<type_traits>

using namespace std;

namespace details {
template 
< 
  template <class,class> class BinaryPred, 
  class FirstOp, 
  class SecondOp, 
  class ... RestOp 
> struct OneToAll {
  static constexpr bool value = 
    BinaryPred<FirstOp,SecondOp>::value && 
    OneToAll<BinaryPred,FirstOp,RestOp...>::value;
};

template 
< 
  template <class,class> class BinaryPred, 
  class FirstOp, 
  class SecondOp, 
  class ... RestOp 
> 
constexpr bool OneToAll_v = 
OneToAll<BinaryPred,FirstOp,SecondOp,RestOp...>::value;

template 
< 
  template <class,class> class BinaryPred, 
  class FirstOp, 
  class SecondOp 
> 
struct OneToAll<BinaryPred,FirstOp,SecondOp> {
  static constexpr bool value = BinaryPred<FirstOp,SecondOp>::value;
};

struct EmptyBase {};

template < class VirtualBase, class ... Bases >
struct MultipleInherit : 
  public
std::conditional_t<OneToAll_v&lt;std::is_base_of,VirtualBase,Bases...>,
         EmptyBase,
         VirtualBase>, 
  public Bases... 
{

  static constexpr std::size_t NBases = sizeof...(Bases)+1;

  template < class ... Args >
  MultipleInherit(Args&&... args)
    :VirtualBase(std::forward<Args>(args)...)
    ,Bases{std::forward<Args>(args)...}...
  {
    cout << "MI()\n";
  }

};

}

using namespace details;

template <class T>
struct Root {
  Root(T& i, const double& d) : ri_(i), d_(d) { cout << "Root()\n"; };
protected:
  T& ri_;
  double d_;
};

template < class T >
struct E : public virtual Root<T> {
  E(T& i, const double& d) : Root<T>(i,d) {
    cout << "E()\n";
  }
};

template < class T >
struct F : public virtual Root<T> {
  F(T& i, const double& d) : Root<T>(i,d) {
    cout << "F()\n";
  }
};

template < class T >
struct G : public MultipleInherit<Root&lt;T>,E<T>,F<T>> {
  using BaseType = MultipleInherit<Root&lt;T>,E<T>,F<T>>;
  G(T& i, const double& d) : Root<T>(i,d),BaseType(i,d) {
    cout << "G()\n";
  }
};

int main(int argc, char* argv[]) {
  int i = 3;
  double d = 4;
  G<int> g(i,d);
}

If I compile with gcc 7.3.0: g++ testbases1.cpp -o testbases1 -g -std=c++14,
I get the expected output:
Root()
E()
F()
MI()
G()
But if I compile with gcc 5.5.0, I get:
Root()
Root()
E()
Root()
F()
MI()
G()

The gcc 5.5.0 is obviously giving the wrong answer because one would expect
the virtual base is only constructed once in this situation. I also tried
clang++ which gives the correct answer too. Is this a GCC bug in 5.5.0 or am
I missing something?



--
Sent from: http://gcc.1065356.n8.nabble.com/gcc-Help-f629689.html



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux