Specialised template function

I have a fairly complicated code used to do simulations of neutron stars that I am trying to port to using pgCC. Long ago we used the portland fortran compilers but now we need the C++ compilers as well. Since the code has serveral template class libraries it is always a pain to get the linking done correctly. After some work, I think I have the right switches for template instatiation but there is a lingering problem in the linking phase.

I have a function call like:

int Output3DVarAs (const cGH *cgh, const char *name, const char *alias)
{
  return ((IOGH<3>*)cgh->extensions[GHExtension3D])->OutputVarAS(name, alias);
}

In another file in the same library I have that (specialized)
template function defined:

template<>
int IOGH<3>::OutputVarAs (const char *name, const char *alias)
{
blah...blah;
}

Which is part of an explicitly instantiated template class IOGH:

template class IOGH<3>;

While linking I get the following error:

/scratch/evans/Cactus/configs/pagh_GRA/lib/libPAGHIOASCII.a(paghioascii.cc.o)(.t
ext+0x733):
In function Output3DVarAs': /scratch/evans/Cactus/configs/pagh_GRA/build/PAGHIOASCII/paghioascii.cc:181: undefined reference to _XCiL_1_3::OutputVarAs__Q2_11PAGHIOASCII20IOGH__tm(char const *, char
const *)’

PAGHIOASCII is the namespace of this library. IOGH is the class name.
The final 3 before the :: is the integer used to specialze the function.
Otherwise the mangling is a mystery to me.

nm shows the following:
0000000000002950 T
OutputVarAs__S__Q2_11PAGHIOASCII20IOGH__tm__9_XCiL_1_3FPCcT1_i
U OutputVarAs__Q2_11PAGHIOASCII20IOGH__tm__9_XCiL_1_3FPCcT1_i

If I remove the definition of a similar, but not specialized, member
function, the linker again complains but asks for a non-mangled name.

This code works with intel, gcc and Irix compilers so should be fairly
portable in theory.

This is with pgCC --instantiate=none. I am evaluating pgCC 5.2-4.

It seems that this (and the 2 other specializations of this function) are
the only thing stoping me from linking.

Any ideas?

Ed

Ed-

All templates (even specialized instances) get instantiated where they
are referenced, not where they are defined. While this code may compile
on other C++ compilers, it is not portable in the strict Ansi sense.

pgCC requires that the source file that instantiates the template must
have a definition of that template. Generally all template definitions
are put in .h files: even specialized instances.

So, put your specialized instance:
int IOGH<3>::OutputVarAs (const char *name, const char *alias)
in a .h file, and include it everywhere it is referenced. This is
the portable solution to your problem.

  • FYI The tool pgdecode reads mangled C++ names from stdin, and outputs
    the demangled name

-Deborah Caruso
ST Microelectronics