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:

int IOGH<3>::OutputVarAs (const char *name, const char *alias)

Which is part of an explicitly instantiated template class IOGH:

template class IOGH<3>;

While linking I get the following error:

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
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?



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