Question

I'm currently trying to write an Artemis like game component/entity system in C++. I was planning on getting this system to work with a cross platform tool for writing applications on Android and iOS called MoSync.

Unfortunately MoSync currently uses an old version of GCC and when porting the library that I had been testing in Visual Studio, I got a whole bunch of errors. Most of these I could solve, but there is one bug with templates that I can't get my head around.

I wrote a small example

template <typename T>
struct Base
{
 static int type;
};

struct Derived : public Base<Derived>
{
};

template <typename T>
int Base<T>::type(-1);

extern "C" int MAMain()
{
 Derived d;
 d.type = 0;
} 

My library uses the Curiously Recursive Template Pattern for defining Components. This example compiles fine in GCC 4.4 and Visual Studio 2010. However when I try to compile this in MoSync (which uses GCC 3.4.6) I get this linker error

C:\MoSync\workspace\pede\main.cpp: Error: Unresolved symbol '__ZN4BaseI7DerivedE4typeE',

Is there a workaround to get this to work in this compiler, or will I have to find another way to define my Components?

Edit* In fact I can make this error occur with an even simpler example:

template <typename T>
struct Component {
    static int t;
};

template <typename T>
int Component<T>::t(-1);

extern "C" int MAMain()
{
    Component<int>::t = 0;
}

Gives this error

C:\MoSync\workspace\Components\main.cpp:9: Error: Unresolved symbol '__ZN9ComponentIiE1tE', 

I guess this might not have anything to do with the Curiously Recursive Template Pattern at all. What can I do to get this to compile under GCC 3.4.6?

Was it helpful?

Solution

According to this bug report on the gcc bugtracker, the problem is caused by specifying a default value in the static variable definition. The code should link if you remove the initialisation as so:

int Base<T>::type;

The bug report seems to have been resolved as not a bug. Despite this, your samples compile fine in GCC 4.4.

To work around this, you can use a class type with a constructor that will automatically initialise itself.

OTHER TIPS

Does adding

int Base<Derived>::type(-1);

helps ?

gcc 3.4 is really starting to be old and don't coep well with template sorcery.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top