In an application I'm developing I have a template function like this:
template<class T>
void CIO::writeln(T item)
{
stringstream ss;
ss << item << '\r' << endl;
write(ss.str());
}
This function is called from several places, with T = const char* and T=std::string. With CodeSourcery Lite 2008.03-41 (GCC 4.3.2) this compiled and linked fine with -O3 compiler flag. However, since I changed to CodeSourcery Lite 2012.03-57 (GCC 4.6.3), compiling with -O3 is OK, but then linking fails with undefined reference to void CIO::writeln<std::string>(std::string)
. With -O2 or lower everything is OK, linking succeeds.
I had a deeper look into this and I discovered something strange in the assembly output: when compiling with -O2, I can find two specializations of the function: one for const char* (_ZN3CIO7writelnIPKcEEvT_
) and one for std::string (_ZN3CIO7writelnISsEEvT_
), but when compiling with -O3, the second specialization is missing, which explains the linking error.
Is this a compiler bug? Is this some weird optimization turned evil?
Thanks in advance!
Edit: this function is in a source file. Following Mike Seymour's comment, I moved it to the header and everything's fine now. I admit that I should've realized this earlier. Nevertheless, it still frightens me that a language rule is checked or not depending on an optimization flag.