Two Bugs of VC++.NET2005 IDE

来源:互联网 发布:阿里云服务器搭建网站 编辑:程序博客网 时间:2024/04/29 20:53

First let’s see a program

/*

Abstract    : A program to show polymophism.

Author      : Lijie Wang

Environment : Visual C++.NET 2005

History     : 2006-10-29

*/

#include<iostream>

using namespace std;

class B1

{

 public:

   virtual void vf1()

   {

        cout<<"B1::vf1"<<endl;      

   }

   virtual void vf2()

   {

        cout<<"B1::vf2"<<endl;

   }

   virtual void vf3()

   {

        cout<<"B1::vf3"<<endl;    

   }

   void B1f(){}

};

 

class B2

{

 public:

   virtual void vf2()

   {

        cout<<"B2::vf2"<<endl;      

   }  

   virtual void vf3() 

   {

        cout<<"B2::vf3"<<endl;     

   }

   virtual void vf4()

   {

        cout<<"B2::vf4"<<endl;

   }

   void B2f(){}

};

 

class D : public B1, public B2

{

public: 

   void vf1()  //overide B1::vf1 and B2::vf1

   {

        cout<<"D::vf1"<<endl;     

   } 

   void vf3()

   {

        cout<<"D::vf3"<<endl;     

   }   

   virtual void vf5()   //additional virtual function

   {

        cout<<"D::vf5"<<endl;

   }

   void Df()  //non virtual function

   {

        cout<<"D::Df"<<endl;

   }

   void Set_A(int n)

   {

        a = n;

        cout<<"D::A="<<a<<endl;

   }

private:

     int a;

};

 

void main()

{

     D d;

     B1 b1;

     B2 b2;

     B1 *pb1 = &d; //pb1 point to the B1-sub-object of D

     B2 *pb2 = &d; //pb1 point to the B2-sub-object of D

 

     d.vf3();

     d.vf5();

     b1.vf1();

     b2.vf3();

 

     pb1->vf1(); //danymic binding

     pb1->vf2(); //danymic binding

     pb1->vf3();

     dynamic_cast<D*>(pb1)->Set_A(1);

 

     pb2->vf2();

     pb2->vf3();

     pb2->vf4();

     dynamic_cast<D*>(pb1)->vf5();

}

The class diagram of this program is shown in Fig 1.

Fig 1. Class Diagram

The structure of d object can be found from the Watch Window while debugging, just like Fig 2:

Fig 2. Structure of d Object

We can find from the structure of the d object that it includes a B1 sub-object and a B2 sub-object with a __vfptr in each one. From the vftables we can see that D::vf1 has overridden the B1::vf3 and B2::vf3, just according to our expectation. But we can not find the new virtual function D::vf5 in the vftables. There are only two __vfptrs in the d object and each belongs to a sub-object. But we know, to support polymorphism the D::vf5 should be in the __vfptr of d object. The only way to satisfy the need is to insert D::vf5 into one of the two __vfptrs of the sub-objects, but we find none.

Let’s see the address of d.vf5 from the Watch Window:

Fig 3. Address of d.vf5

This indicates that the address of d.vf5 is 0x00411208.

Then we can find the address of the vftable of B1 sub-object or say d.B1.__vfptr from the Watch Window:

Fig 4. Address of d.B1.__vfptr

So the address of the B1.__vfptr of d is 0x00417744, then we turn to the Memory Window to check what is stored in the vftable of B1 sub-object:

Fig 5. Memory content from of vftable of B1 sub object of d

From the picture above we can see that the four successive words stored in the vftable of B1 sub-object are: 0x004111e5, 0x00411091, 0x004111bd, 0x00411208. 0x00411208 is just the address of d.vf5, this indicates that d.vf5 is actually inserted in the end of the first sub-object vftable of d, here is vftable of B1 sub-object. But we can not find it from Fig 2. So I think this is a bug of the VC++.NET IDE (I use VC++.NET 2005).

Then the we modify the program by replacing each vf* function by f*. Then the structure of the d object in the Watch Window is shown in the Fig 6.

Fig 6. Structure of d Object After Modification

From the Fig 6 we find D::vf1, B1::vf2 and D::vf3 in the vftable of B1 sub-object, which is obviously not right.  But if you create a new project and copy the program, the displayed structure of d will be all right. I think this is also a bug of VC++.NET IDE.

 

 
原创粉丝点击