This is the mail archive of the gcc-help@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]
Other format: [Raw text]

Removing data member from virtual base causes wrong member function to be called


I've trawled through mailing list archives, Google and C++ standards
and can find nothing about why this is occurring.. I'm hoping someone
here might be able to help.

A minimal example, with a bit of context, is this:

#include <iostream>
using namespace std;

struct Resource {
   //int dummy;
   virtual void initMenu() {
       cerr << "Resource::initMenu()" << endl;
   }
   virtual ~Resource() {}
};
struct Event {
   virtual void trigger() = 0;
   virtual ~Event() {}
};
struct Image :
public virtual Resource,
public virtual Event {
   virtual void trigger() {
       cerr << "Image::trigger()" << endl;
   }
};

static void* make_image() {
   return new Image();
}

int main() {
   static_cast<Event*>(make_image())->trigger();
   return 0;
}


It started off as an example of why virtual bases are needed, but it also behaves differently when the data member is removed from the base class.

The above code prints out "initMenu()" on g++ (3.3.6, 3.4.6, 4.1.0 and
4.2.0) and icc (9.1.049) -- both under Linux. Microsoft's compiler
(2005/VC++8 free and 2003/VC++7 non-free) just "segfaults" (status
access violation) when I try to run the code (under Windows). Clearly,
I "want" it to print out "trigger()".

With g++ I compile with -Wall -Wextra -ansi -pedantic and get no
errors or warnings.

With the 'dummy' member present (uncommented), it prints out
"trigger()" as expected. Note that without dummy, sizeofs for
Resource/Event/Image are 4/4/8, with dummy they are 8/4/12. These
sizes do not change if the inheritance is not virtual. However,
without virtual inheritance, it always prints out 'initMenu()' with or
without the dummy member. (Member functions are virtual in all my
tests).

Can anyone tell me what's going on?

Is this a compiler bug or intentional (i.e. whether or not 'dummy' is
present -- identical behaviour on icc seems to suggest that it is not
a bug in gcc)?

Is virtual inheritance really making the "right" thing happen (at
least when 'dummy' IS present) or is this an accident?


I know there is no "diamond inheritance" here, which is usually mentioned in the same sentence as "virtual inheritance", but changing the inheritance to virtual seemed to fix the problem -- but only if the base has at least one data member. It's that last bit that has me confused.

Thanks heaps,
 Trent.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]