gpt4 book ai didi

c++ - GCC 4.6.3 - 模板特化受优化级别影响?

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:18:00 25 4
gpt4 key购买 nike

在我正在开发的应用程序中,我有一个这样的模板函数:

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 进行编译是可以的,但随后链接失败并显示 undefined reference to 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。

目标文件 1 只有在目标文件 2 包含 CIO::writeln 的定义时才可用。如果源文件 2 中的调用被内联,目标文件 2 将不包含它的定义。如果调用未内联,则定义可用。

评论中给出的解决方案,将定义移动到头文件中,是正确的。

关于c++ - GCC 4.6.3 - 模板特化受优化级别影响?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19928070/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com