views:

364

answers:

2

Hi all!

I have a problem with Visual Studio 2008 concerning virtual inheritance.

Consider the following example:

#include<iostream>

class Print {
    public:

    Print (const char * name) {
        std::cout << name << std::endl;
    }
};

class Base : public virtual Print {
    public:

    Base () : Print("Base") {}
};

class A : public Base {
    public:

    A () : Print("A") {}
};

class B : public A {
    public:

    B () : Print("B") {}
};

int main (int argc, char** argv) {
    A a; // should print "A"
    B b; // should print "B"
    return 0;
}

This code compiles just fine if I use gcc on my linux machine. But if I try to build the same on windows with Visual Studio, the compilation fails with error message "error C2614: 'B': illegal member initialization: 'Print' is not a base or member."

Why does this not work?

+2  A: 

From the standard [class.base.init]: "Unless the mem-initializer-id names a nonstatic data member of the constructor’s class or a direct or virtual base of that class, the mem-initializer is ill-formed."

Evidently gcc interprets your case as legal as Print is a non-direct, but virtual base of B, however MSVC 2008 doesn't see Print as a virtual base of B - only a virtual base of a non-virtual base. (Incidentally, your example compiles on VS2005, so it's a surprising change in behaviour.)

I'd lean towards the gcc interpretation as being correct (otherwise the phrasing 'a direct base' would have been sufficient).

To work around this problem, you could derive B virtually from Print. As Print is already a virtual base of A this doesn't have any overall effect on the class layout or the number of base class Print sub-objects.

Alternatively, you could add pass through constructors to Base and A that take a const char* and pass the constructor parameter through to the Print constructor.

Charles Bailey
Thanks for quoting the standard. As you and others noted, the code compiles on various VS installations. Thus I recompiled the same code on another machine where the error message just disappeared. Maybe the VS installation on my machine is corrupted.
swegi
A: 

What version of Visual Studio are you using? The code you posted works fine for me with VC 9 (specifically 15.00.21022.08), and VC 6 as well as a few other compilers.

Are you sure that by mistake class B doesn't look like this in Visual Studio:

class B {  //  note: no base class
    public:

    B () : Print("B") {}
};
Michael Burr
No, code is like in my example. See my comment on the other answer.
swegi
What exact version of the compiler does it fail for? Change the "Suppress Startup Banner" property of the project or use the command line to get that information.
Michael Burr