Saturday, 28 September 2013

C++: Possible GCC 4.7.1 bug related to virtual templated multiple inheritance?

C++: Possible GCC 4.7.1 bug related to virtual templated multiple
inheritance?

I have code with inheritance that looks like this:
B
/ \
/ \
/ \
BI D
(template) /
\ /
\ /
DI
(template)
The templates are instantiated at runtime through factories, and
everything is glued together with boost::any. Things should work fine,
except they don't. I get segfaults and obscure crashes.
I have sort of pinpointed the problem. It seems to be a bug, but I'm not a
C++ expert, and I may be unwittingly invoking undefined behavior.
A fully independent, working example is contained in the files below.
Here's the main.cpp file:
#include <iostream>
#include "base.hpp"
int main(void)
{
std::unique_ptr<Base> base = Base::create("Hello world!");
std::cout << "base -> " << base.get() << std::endl;
base->check();
return 0;
}
Base::create() is a factory method which calls another factory method,
Derived::create(), which instantiates class DerivedImpl<T>.
base->check() simply prints the value of this.
One would expect of the program to print the exact same address; it's same
object, after all. Alas, it doesn't. In my case, the offset is by 4, but
that's arbitrary.
The rest of the source is below. Run the example for yourself. I'd like
this mystery, if there even is one, resolved.
base.hpp
#ifndef BASE_HPP
#define BASE_HPP
#include <memory>
#include <string>
class Base
{
public:
static std::unique_ptr<Base> create(const std::string&);
virtual ~Base();
virtual void check(void) = 0;
protected:
virtual void init(const std::string&) = 0;
virtual void init(void) = 0;
};

No comments:

Post a Comment