Program provoking bug: template < class lstype > class X { friend void mod(X *r) {} }; template < class T > void slam ( T *value ) { char *p; mod ( value ); } int main( int argc, char **argv ) { X<double> x; slam( &x ); #if 0 // Changing this 0 to 1 has an effect on success of linkage. mod( &x ); #endif } Compilation output: g++ ec.cc /tmp/ccoqLzDf.o: In function `void slam<X<double> >(X<double> *)': /tmp/ccoqLzDf.o(.void gnu.linkonce.t.slam<X<double> >(X<double> *)+0xb): undefined reference to `void mod<double>(X<double> *)' collect2: ld returned 1 exit status Calling mod from main seems to cause the function to be instantiated, but as is, mod is NOT being instantiated. using egcs-1.1.2-12, egcs-c++-1.1.2-12, kernel-2.2.5-15 Brian
Hmm. I had the same problem when using stringfunctions in normal C. Turned out there where infact macro's. Solved it by putting the function name beween ()'s.
Putting mod in parentheses has no effect, so the comment about macros seems to be inapplicable to this test case.
I was able to reproduce this with the GCC (version egcs 1.1.2) which ships with Red Hat 6.0. If I use the latest GCC from http://gcc.gnu.org/, the problem goes away. Therefore, I conclude that this is one of the many C++ fixes in the latest GCC. So the good news is that the fix exists. The bad news is that upgrading to that compiler involves recompiling all C++ libraries (e.g. stdc++) due to changes in the C++ ABI. Because of this compatibility issue, Red Hat Linux will not be shipping with this newer compiler for some time to come.