加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – GCC 4.6.3 – 模板专业化受优化级别的影响?

发布时间:2020-12-16 07:06:33 所属栏目:百科 来源:网络整理
导读:在我正在开发的应用程序中,我有一个这样的模板函数: templateclass Tvoid 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
在我正在开发的应用程序中,我有一个这样的模板函数:

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将不包含它的定义.如果调用没有内联,则可以使用定义.

注释中给出的解决方案将定义移动到头文件中是正确的.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读