samedi 2 mai 2015

Undefined reference to static const member in g++ if no using code is linked

the project I'm working on currently consists of three basic build targets:

  • The core, containing almost all of the classes
  • The tests, containing only a few test classes and a main function. They touch (hopefully) every piece of code in the core.
  • The client, which only consists of a main function that used to create one object from the core and call what currently is a Hello World function. Now the main is completely empty and it didn't do anything to kill the error.

The linking error appears only if I build the client. It's about a static const in the core, looking like this:

class Transition
{
private:
  Transition();
  ...more declarations...

public:
  static const Transition NO_TRANSITION
  ...more declarations...
}

Usage in Map.cpp:

Transition Map::searchTransition(Coordinate p, Direction d)
{
  ...code...
  return Transition::NO_TRANSITION;
}

This is what I'm told by by g++:

obj/gpp/Debug/Game/Map/Map.o:Map.cpp: (.rdata$.refptr._ZN10Transition13NO_TRANSIT IONE[.refptr._ZN10Transition13NO_TRANSITIONE]+0x0): undefined reference to `Transition::NO_TRANSITION'

Map.cpp is also part of the core, it includes Transition.h, and the .o files are right where they are expected to be. There are no forward declarations between the two involved files.

What bothers me most: This only happens if I build the client. It works perfectly fine if I link the core with the test classes and their main instead, which means only more code to be linked. The only thing removed is a tiny or even empty main function that got replaced with a much bigger one that actually uses Map and Transition.

Also, that static const is not new and has never caused problems in the past. Since the tests accept it, I would think everything is perfectly fine, but apparently only as long as the tests are linked to it.

I've tried recreating the error in a smaller project, with the makefile being (mostly) the same, but the error won't show up. I have absolutely no idea what the important difference might be.

I'm using g++ 4.8 with -std=c++11 under cygwin. Visual Studio accepts the same code without trouble, and under true linux I couldn't test yet, though I expect it to be the same as with cygwin.

Does anybody have an idea what might be going wrong here?

Aucun commentaire:

Enregistrer un commentaire