Bug 44733 - a bug with virtual base class (?)
Summary: a bug with virtual base class (?)
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.4.3
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-06-30 21:17 UTC by Michael
Modified: 2010-06-30 22:28 UTC (History)
1 user (show)

See Also:
Host: i686-pc-linux
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Michael 2010-06-30 21:17:04 UTC
Compiling and executing this code:
---------------------------------
#include <iostream>
using namespace std;

void *p;

struct vbase
{
  int a;
  virtual vbase* me() = 0;
  void set_p() { p = me(); };
};

struct derived : virtual vbase
{
  int b;
  derived* me()
  {
    cout << "derived::me() = " << this << endl;
    return this;
  };
};

int main()
{
  derived t;
  t.set_p();
  cout << "p = " << p << endl;
};
---------------------------------

produce the strange results, the output is:
---------------------------------
derived::me() = 0xbff41ab0
p = 0xbff41ab8
---------------------------------

It doesn't metter is me() a pure virtual function or has a body in 'vbase' class.

Small changes in code, any of these:
1) declaring the return type of me() as void*
2) commenting data member 'int a' in 'vbase' class
3) making 'vbase' non virtual base of 'derived'
give the right result: saved 'this' in 'p' is equal to 'this' of derived class.

Sorry, don't know how to summarize the problem, is it a bug or I misunderstood some c++ subtle points...
Comment 1 Jonathan Wakely 2010-06-30 22:28:43 UTC
conversion from derived* to vbase* involves adjusting a pointer

in the context of vbase::set_p the value returned from me() is converted to vbase* so the pointer is adjusted

try changing derived::me() to this:

  int b;
  derived* me()
  {
    cout << "derived::me() = " << this << endl;
    cout << "derived::me() as vbase = " << (vbase*)this << endl;
    return this;
  };

you will see that the value is different, and the second value is the one assigned to ::p