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进行编译是正常的,但是然后链接失败,未定义引用voID CIO :: writeln< std :: string>(std :: string) .使用-O2或更低的一切都可以,链接成功.
我对此进行了深入研究,并在程序集输出中发现了一些奇怪的东西:当使用-O2进行编译时,我可以找到函数的两个特化:一个用于const char *(_ ZN3CIO7writelnIPKcEEvT_),另一个用于std :: string(_ZN3CIO7writelnISsEEvT_),但在使用-O3进行编译时,缺少第二个特化,这解释了链接错误.
这是编译器错误吗?这是一些奇怪的优化变成了邪恶吗?
提前致谢!
编辑:此功能位于源文件中.在Mike Seymour的评论之后,我把它移到标题上,现在一切都很好.我承认我应该早点意识到这一点.然而,根据优化标志,检查或不检查语言规则仍然让我感到害怕.
解决方法 与其他答案所说的不同,这可能不是编译器错误.-O3启用的优化之一是函数内联.我认为发生的是:
源文件1在没有定义的情况下调用CIO :: writeln.它被编译为目标文件1.
源文件2在其定义可用时调用CIO :: writeln.它被编译为目标文件2.
只有当目标文件2包含CIO :: writeln的定义时,目标文件1才可用.如果源文件2中的调用被内联,则对象文件2将不包含它的定义.如果调用没有内联,则可以使用定义.
注释中给出的解决方案将定义移动到头文件中是正确的.
总结以上是内存溢出为你收集整理的c – GCC 4.6.3 – 模板专业化受优化级别的影响?全部内容,希望文章能够帮你解决c – GCC 4.6.3 – 模板专业化受优化级别的影响?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)