私が開発しているアプリケーションには、次のようなテンプレート関数があります。
template<class T>
void CIO::writeln(T item)
{
stringstream ss;
ss << item << '\r' << endl;
write(ss.str());
}
この関数は、T = const char* および T=std::string を使用して、いくつかの場所から呼び出されます。CodeSourcery Lite 2008.03-41 (GCC 4.3.2) を使用すると、これは -O3 コンパイラ フラグで正常にコンパイルおよびリンクされます。ただ、CodeSourcery Lite 2012.03-57(GCC 4.6.3)に変更したので、-O3でコンパイルはOKなのですが、その後でリンクに失敗しundefined reference to void CIO::writeln<std::string>(std::string)
ます。-O2 以下ですべて問題なく、リンクは成功します。
これを詳しく調べたところ、アセンブリの出力で何か奇妙なことがわかりました。-O2 でコンパイルすると、関数の 2 つの特殊化が見つかります。1 つは const char* ( _ZN3CIO7writelnIPKcEEvT_
) 用で、もう 1 つは std::string ( _ZN3CIO7writelnISsEEvT_
) 用ですが、 -O3 でコンパイルすると、2 番目の特殊化が欠落しており、これがリンク エラーを説明しています。
これはコンパイラのバグですか? これは奇妙な最適化が悪に変わったのでしょうか?
前もって感謝します!
編集: この関数はソース ファイルにあります。Mike Seymour のコメントに従って、ヘッダーに移動したところ、すべて問題ありません。私はこれにもっと早く気づくべきだったことを認めます。とはいえ、最適化フラグによって言語ルールがチェックされたりチェックされなかったりするのは恐ろしいことです。