This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
The problem: g++ seems to have problem during construction when the
inherance is too deep and when this inherance is
virtual:
Result of ./test_virtual execution:
0xffbef3e4 constructor without argument of class A
--> 0xffbef3e8 constructor without argument of class B <--
Strange behavior
0xffbef3f0 constructor of class C
0xffbef3e0 constructor of class D
d constructed
0xffbef3d4 constructor without argument of class A
0xffbef3d8 constructor of class B
0xffbef3d0 constructor of class C
c constructed
0xffbef3d0 destructor of class C
0xffbef3d8 destructor of class B
0xffbef3d4 destructor of class A
0xffbef3e0 destructor of class D
0xffbef3f0 destructor of class C
0xffbef3e8 destructor of class B
0xffbef3e4 destructor of class A
The good behavior would be:
0xffbef3e4 constructor without argument of class A
--> 0xffbef3e8 constructor of class B <--
0xffbef3f0 constructor of class C
0xffbef3e0 constructor of class D
d constructed
0xffbef3d4 constructor without argument of class A
0xffbef3d8 constructor of class B
0xffbef3d0 constructor of class C
c constructed
0xffbef3d0 destructor of class C
0xffbef3d8 destructor of class B
0xffbef3d4 destructor of class A
0xffbef3e0 destructor of class D
0xffbef3f0 destructor of class C
0xffbef3e8 destructor of class B
0xffbef3e4 destructor of class A
This test shows that 'c' object construction is correct but not 'd' object construction
The source code: just a file called virtual.cpp:
//*****************************************************************************
// File name: virtual.cpp
// Description: Test a possible bug in g++ about virtual inherance
//*****************************************************************************
// Version tested: 2.91.66 and 2.95.2
// Command line: g++ -o test_virtual -Wall -ggdb -O0 virtual.cpp
// Normal result:
// 0xffbef3e4 constructor without argument of class A
// --> 0xffbef3e8 constructor of class B <--
// 0xffbef3f0 constructor of class C
// 0xffbef3e0 constructor of class D
// d constructed
// 0xffbef3d4 constructor without argument of class A
// 0xffbef3d8 constructor of class B
// 0xffbef3d0 constructor of class C
// c constructed
// 0xffbef3d0 destructor of class C
// 0xffbef3d8 destructor of class B
// 0xffbef3d4 destructor of class A
// 0xffbef3e0 destructor of class D
// 0xffbef3f0 destructor of class C
// 0xffbef3e8 destructor of class B
// 0xffbef3e4 destructor of class A
// Bad result:
// 0xffbef3e4 constructor without argument of class A
// --> 0xffbef3e8 constructor without argument of class B <--
// 0xffbef3f0 constructor of class C
// 0xffbef3e0 constructor of class D
// d constructed
// 0xffbef3d4 constructor without argument of class A
// 0xffbef3d8 constructor of class B
// 0xffbef3d0 constructor of class C
// c constructed
// 0xffbef3d0 destructor of class C
// 0xffbef3d8 destructor of class B
// 0xffbef3d4 destructor of class A
// 0xffbef3e0 destructor of class D
// 0xffbef3f0 destructor of class C
// 0xffbef3e8 destructor of class B
// 0xffbef3e4 destructor of class A
// Bug: a too deep virtual inherance doesn't run correctly during
// construction.
// Because: c construction is correct but not d construction
#include <iostream>
//*****************************************************************************
class A;
class B;
class C;
class D;
class A
{
public:
//***************************************************************************
// Constructors/Destructor
//***************************************************************************
//---------------------------------------------------------------------------
// Name: A
// Task: Constructor without argument
//---------------------------------------------------------------------------
explicit A(void);
//---------------------------------------------------------------------------
// Name: ~A
// Task: Destructor
//---------------------------------------------------------------------------
virtual ~A();
};
//*****************************************************************************
class B
: virtual public A
{
public:
//***************************************************************************
// Constructors/Destructor
//***************************************************************************
//---------------------------------------------------------------------------
// Name: B
// Task: Constructor without argument
//---------------------------------------------------------------------------
explicit B(void);
//---------------------------------------------------------------------------
// Name: B
// Task: Constructor with the argument `a'
//---------------------------------------------------------------------------
explicit B(const int a);
//---------------------------------------------------------------------------
// Name: ~B
// Task: Destructor
//---------------------------------------------------------------------------
virtual ~B();
private:
//***************************************************************************
// Implementation
//***************************************************************************
//---------------------------------------------------------------------------
// Name: i
// Description: an integer variable
//---------------------------------------------------------------------------
int i;
};
//*****************************************************************************
class C
: virtual public B
{
public:
//***************************************************************************
// Constructors/Destructor
//***************************************************************************
//---------------------------------------------------------------------------
// Name: C
// Task: Constructor with the argument `a'
//---------------------------------------------------------------------------
explicit C(const int a);
//---------------------------------------------------------------------------
// Name: ~C
// Task: Destructor
//---------------------------------------------------------------------------
virtual ~C();
};
//*****************************************************************************
class D
: virtual public C
{
public:
//***************************************************************************
// Constructors/Destructor
//***************************************************************************
//---------------------------------------------------------------------------
// Name: D
// Task: Constructor with the argument `a'
//---------------------------------------------------------------------------
explicit D(const int a);
//---------------------------------------------------------------------------
// Name: ~D
// Task: Destructor
//---------------------------------------------------------------------------
virtual ~D();
};
//*****************************************************************************
//***************************************************************************
// Constructors/Destructor
//***************************************************************************
//---------------------------------------------------------------------------
// Name: A
// Task: Constructor without argument
//---------------------------------------------------------------------------
A::A(void)
{
cout<<this<<" constructor without argument of class
A"<<endl;
}
//---------------------------------------------------------------------------
// Name: ~A
// Task: Destructor
//---------------------------------------------------------------------------
A::~A()
{
cout<<this<<" destructor of class A"<<endl;
}
//*****************************************************************************
//***************************************************************************
// Constructors/Destructor
//***************************************************************************
//---------------------------------------------------------------------------
// Name: B
// Task: Constructor without argument
//---------------------------------------------------------------------------
B::B(void)
{
cout<<this<<" constructor without argument of class
B"<<endl;
}
//---------------------------------------------------------------------------
// Name: B
// Task: Constructor with the argument `a'
//---------------------------------------------------------------------------
B::B(const int a)
{
cout<<this<<" constructor of class B"<<endl;
i=a;
}
//---------------------------------------------------------------------------
// Name: ~B
// Task: Destructor
//---------------------------------------------------------------------------
B::~B()
{
cout<<this<<" destructor of class B"<<endl;
}
//*****************************************************************************
//***************************************************************************
// Constructors/Destructor
//***************************************************************************
//---------------------------------------------------------------------------
// Name: C
// Task: Constructor with the argument `a'
//---------------------------------------------------------------------------
C::C(const int a)
:B(a)
{
cout<<this<<" constructor of class C"<<endl;
}
//---------------------------------------------------------------------------
// Name: ~C
// Task: Destructor
//---------------------------------------------------------------------------
C::~C()
{
cout<<this<<" destructor of class C"<<endl;
}
//*****************************************************************************
//***************************************************************************
// Constructors/Destructor
//***************************************************************************
//---------------------------------------------------------------------------
// Name: D
// Task: Constructor with the argument `a'
//---------------------------------------------------------------------------
D::D(const int a)
:C(a)
{
cout<<this<<" constructor of class D"<<endl;
}
//---------------------------------------------------------------------------
// Name: ~D
// Task: Destructor
//---------------------------------------------------------------------------
D::~D()
{
cout<<this<<" destructor of class D"<<endl;
}
//*****************************************************************************
//---------------------------------------------------------------------------
// Name: main
// Task: Entry point
//---------------------------------------------------------------------------
int main(int argc,
char *argv[])
{
D d(10);
cout<<"d constructed"<<endl;
C c(10);
cout<<"c constructed"<<endl;
return 0;
}
-- François Bertel DIIC3-INC bertel@ifsic.univ-rennes1.fr fbertel@irisa.fr
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |