Sun Studio C++ - template methods not generated in obj file
Hi,
I've a template class declared in .hxx file and the methods of this class are defined outline in a separate .cpp file. When I compile this .cpp file, with following CC commandline, I find that all the methods from this class are not defined in the final .o file.
Why is it like this? Please help.
"CC -v" = [CC: Sun WorkShop 6 update 2 C++ 5.3 Patch 111685-24 2006/11/03]
/sw/workshop6u2/SUNWspro/bin/CC -g -D_DEBUG -c -KPIC -mt -D_SUN -D_SUNOS_SOURCE -D_VMT -D_SOLARIS_2_8 -features=rtti -DSOLARIS -I/home/gborse/pxm/include -o 5.8-D/suht.o suht.cpp
nm 5.8-D/suht.o
./5.8-D/suht.o:
[Index]ValueSizeType Bind Other ShndxName
[2]| 0|0|NOTY |LOCL |0|3|Bbss.bss
[3]| 0|0|NOTY |LOCL |0|4|Ddata.data
[4]| 0|0|NOTY |LOCL |0|5|Drodata.rodata
[9]| 0|0|NOTY |GLOB |0|UNDEF |_GLOBAL_OFFSET_TABLE_
[6]|432|76|FUNC |GLOB |0|2|__1cKuht_item_tEdata6M_pv_
[8]|232|84|FUNC |GLOB |0|2|__1cKuht_item_tInextitem6M_p0_
[7]|336|80|FUNC |GLOB |0|2|__1cKuht_item_tJtotalSize6M_I_
[5]|16|200|FUNC |LOCL |0|2|__1cO_default_hashf6Fipkc_i_
[1]| 0|0|FILE |LOCL |0|ABS|suht.cpp
On linkingthis with the executable I get errors as:-
Undefinedfirst referenced
symbolin file
void shared_U_HashTable<CE_INSTR>::Destroy() SunOS_5.8-D/cemain.o
int shared_U_HashTable<CE_INSTR>::suhtAdd(const char*,void**) SunOS_5.8-D/cemain.o
int shared_U_HashTable<CE_INSTR>::Init(int,int,int(*)(int,const char*)) SunOS_5.8-D/cemain.o
int shared_U_HashTable<CE_INSTR>::suhtGet(const char*,void**)const SunOS_5.8-D/ceidb.o
Am I missing something? Please help.
# 2
Hi,
I've a template class declared in .hxx file and the
methods of this class are defined outline in a
separate .cpp file. When I compile this .cpp file,
with following CC commandline, I find that all the
methods from this class are not defined in the final
.o file.
Why is it like this? Please help.
"CC -v" = [CC: Sun WorkShop 6 update 2 C++ 5.3 Patch111685-24 2006/11/03]</div>
This compiler is old and no longer supported. Can you use Studio 11 (which is available for free)?
<div class="jive-quote">/sw/workshop6u2/SUNWspro/bin/CC -g -D_DEBUG -c -KPIC
-mt -D_SUN -D_SUNOS_SOURCE -D_VMT -D_SOLARIS_2_8
-features=rtti -DSOLARIS -I/home/gborse/pxm/include
-o 5.8-D/suht.o suht.cpp</div>
<div class="jive-quote">nm 5.8-D/suht.o
./5.8-D/suht.o:</div>
<div class="jive-quote">[Index]ValueSizeType Bind Other Shndx
Name
[2]| 0|0|NOTY |LOCL |0|3
|Bbss.bss
| 0|0|NOTY |LOCL |0|4
|Ddata.data
| 0|0|NOTY |LOCL |0|5
|Drodata.rodata
| 0|0|NOTY |GLOB |0|UNDEF
|_GLOBAL_OFFSET_TABLE_
]|432|76|FUNC |GLOB |0|2
|__1cKuht_item_tEdata6M_pv_
|232|84|FUNC |GLOB |0|2
|__1cKuht_item_tInextitem6M_p0_
|336|80|FUNC |GLOB |0|2
|__1cKuht_item_tJtotalSize6M_I_
|16|200|FUNC |LOCL |0|2
|__1cO_default_hashf6Fipkc_i_
| 0|0|FILE |LOCL |0|ABS
|suht.cpp</div>
In itself, there's no problem here. This version of the Sun C++ compiler maintains a database of object files containing instantiations (in the SunWS_cache directory). Try searching there to find your missing instances:
find SunWS_cache -name "*.o" -exec nm -C {} \; | egrep shared_U_HashTable
<div class="jive-quote"> linking this with the executable I get errors as:-
ndefinedfirst referenced
symbolin file
oid shared_U_HashTable<CE_INSTR>::Destroy()
SunOS_5.8-D/cemain.o
int shared_U_HashTable<CE_INSTR>::suhtAdd(const
char*,void**) SunOS_5.8-D/cemain.o
int
shared_U_HashTable<CE_INSTR>::Init(int,int,int(*)(int,
const char*)) SunOS_5.8-D/cemain.o
int shared_U_HashTable<CE_INSTR>::suhtGet(const
char*,void**)const SunOS_5.8-D/ceidb.o
Am I missing something? Please help.
I can imagine two problems. Either you are not linking correctly (usually this means linking with ld directly, or with cc). You should link with CC, and not use any of the template options that inhibit the correct behaviour.
Alternatively, you simply are not instantiatiing your templates correctly. Just compiling a C++ source file containing template declarations and definitions will not trigger instantiation. Roughly speaking, there are two possible approaches:
a. Explicit instantiation. Sometimes called manual instantiation. Here you have a declaration file (say HashTable.h), a definition file (say HashTable.hpp). You have a cource file include both, and also explicit instantiation. Then in the source files where you want to use the templatized classes/functions, you just need to include HashTable.h. The drawback of this is that it can be slow to compile the instantiations, which may also be bloated with unused code. It may be quicker to compile the user code.
b. Implicit instantiation. In this case, the user code needs to see both declaration and defintion. The compiler will instantiate the templates that it needs, where it needs them. It won't instantiate things that it doesn't need. There may be bloat of you have many user files that instantiate the same classes/functions.
Paul
# 3
Read carefully chapters 7 on compiling templates in the WS6u2 C++ Users Guide for addtional information.
In particular: If you put template declarations in file foo.h (or foo.hxx), file foo.cc should contain nothing but definitions of templates declared in foo.h. File foo.cc should not include foo.h, and should not be compiled directly. It should not contain definitions of anything else.
When you include foo.h in a compilation, file foo.cc will be automatically included in the compilation whenever a definition is needed.
Finally, WS6u2 is obsolete, End Of Life, and little support is available for it. Unless you have a particular reason why you must use this antique compiler, you should upgrade to Sun Studio 11, which is free. It is a much better product by all possible measures. You can get it here:
http://developers.sun.com/sunstudio
Among many other improvements, current versions of Sun C++ no longer use a template cache, which was the source of hard-to-find problems.