Undefined symbol in shared library with static class member

Hi,

Here is a strange problem I am currently experiencing with ROOT v5.18.00a (macosx tiger) when loading of a shared library designed to be used with ROOT. Any help will be warmly welcomed! Many thanks in advance.

Best regards,
Andry.

------------------------problem–description----------------------------------

I reduced the code to the following small sample:

-------------------------------------------------------header
#ifndef _COLLIDER_H
#define _COLLIDER_H
#include “TROOT.h”

class _Collider_small {

public:
static double CMSEnergy();

private:
static double cmsEnergy;

public:
ClassDef(_Collider_small,0);
};

#endif

-------------------------------------------------------C file
#include “_Collider_small.h”

ClassImp(_Collider_small);

using namespace std;

double _Collider_small::CMSEnergy() {
return cmsEnergy;
}

The makefile is attached and makes an include of Makefile.arch which can be found into $ROOTSYS/test/

The compilation was successful. But when loading the created library in ROOT, it fails:


root [0] gSystem->Load("_Events.so")
dlopen error: dlopen(/Volumes/Unix/workarea/jin022008/code/./_Events.so, 9): Symbol not found: __ZN15_Collider_small9cmsEnergyE
Referenced from: /Volumes/Unix/workarea/jin022008/code/./_Events.so
Expected in: dynamic lookup

Load Error: Failed to load Dynamic link library /Volumes/Unix/workarea/jin022008/code/./_Events.so
(int)(-1)
*** Interpreter error recovered ***

Now, if I remove the “static” word in the declarations in the header file,
the compilation is fine, and the library loads successfully in ROOT:


root [0] gSystem->Load("_Events.so")
(int)0

Now, if I use the following header and C files, the compilation and the library loading are also fine:

-------------------------------------------------------header
#ifndef _COLLIDER_H
#define _COLLIDER_H
#include “TROOT.h”

class _Collider_small {

public:
static double CMSEnergy();

public:
ClassDef(_Collider_small,0);
};

#endif
-------------------------------------------------------C file
#include “_Collider_small.h”

ClassImp(_Collider_small);

using namespace std;

double _Collider_small::CMSEnergy() {
return 200;
}

It seems that there is a problem with the handling of a non-constant static data class member. Indeed, the following header and C files compile and are successfully loaded. But the problem is that I need non-constant static data member which value remains the same for all instances of that class. I also saw this problem when the type of the static data class member is a ROOT class (TF1* for e.g.).

-------------------------------------------------------header
#ifndef _COLLIDER_H
#define _COLLIDER_H
#include “TROOT.h”

class _Collider_small {

public:
static double CMSEnergy();

private:
const static double cmsEnergy;

public:
ClassDef(_Collider_small,0);
};
#endif
-------------------------------------------------------C file
#include “_Collider_small.h”

ClassImp(_Collider_small);

using namespace std;

const double _Collider_small::cmsEnergy = 200;

double _Collider_small::CMSEnergy() {
return cmsEnergy;
}

makefile.txt (1.44 KB)

Hi,

you need to define a static data member, not just declare it. Check your favorite C(++) book. Put double _Collider_small::cmsEnergy; into your source file. And naming a class to start with an underscore is a bad idea; check the web for reasons.

Cheers, Axel.

Hi Axel,

Thanks for your answer. I did not think about a C++ problem since the compilation had no error, not even any warning about this data class member.

Best regards,
Andry.