【问题标题】:Why won't this manipulator link with -O3?为什么这个操纵器不与 -O3 链接?
【发布时间】:2013-10-29 17:01:24
【问题描述】:

我定义了一个操纵器:

inline std::ostream& my_manip(std::ostream& os);

我是这样使用的:

std::cout << my_manip << ...;

在调试和发布模式下使用 Boost.bjam 编译所有这些都很好。但是,当需要链接时,我仅在发布模式下收到以下错误:

Undefined symbols for architecture x86_64:
  "std::__1::basic_ostream<char, std::__1::char_traits<char> >::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >& (*)(std::__1::basic_ostream<char, std::__1::char_traits<char> >&))", referenced from:
      my_routine in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

或者,更清晰:

Undefined symbols for architecture x86_64:
  "std::ostream::operator<<(std::ostream& (*)(std::ostream&))", referenced from:
      my_routine in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

如果我注释掉操纵器,一切都可以在调试和发布模式下编译和链接。

如果我留在操纵器中,我可以通过使用 -O0 重建项目来解决链接器错误,但是如果我的发布模式是 bjam 默认值 (-O3),我会更喜欢它。

我正在运行 Xcode 4.6.2 及其相关的 clang:

Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn)
Target: x86_64-apple-darwin12.5.0
Thread model: posix

如何让这个操纵器正确链接优化?

【问题讨论】:

  • 似乎很多人在更新到 Mavericks 后开始出现链接器错误... 这个 SO 帖子有帮助吗:?stackoverflow.com/questions/19550436/…
  • @AndyG:感谢您的链接,不幸的是它似乎无关。与-O0 编译的源链接不会产生错误,因此我能够获得 something 进行链接。而且我还在运行 10.8.5 和 Xcode 4.6.2。

标签: c++11 clang linker-errors bjam iomanip


【解决方案1】:

删除inline。我怀疑您在某个标题中声明了操纵器并且仅在一个翻译单元中定义?使用inline,您正在更改符号的可见性,这可能意味着编译器生成了函数但它没有导出符号以便其他翻译单元可以看到它,即链接器找不到它。

【讨论】:

  • 如果我放弃内联,我会得到重复的符号错误(我在多个翻译单元中使用这个操纵器。)使它static 似乎已经解决了这个问题。谢谢!
  • 抱歉,我关闭的太早了。删除内联并没有解决问题,添加(或删除)static 限定符也没有解决问题。我还将例程模板化为采用basic_ostream 并且链接器错误仍然存​​在。
  • @fbrereto 想编辑您的问题并添加 real 代码吗?
  • 在按照您的要求进行操作的过程中,我意识到我没有尝试删除inline,然后将代码体从标题中移出到源文件中,从而消除了重复的符号错误。这似乎永远解决了问题。谢谢!
猜你喜欢
  • 1970-01-01
  • 2012-01-07
  • 1970-01-01
  • 1970-01-01
  • 2010-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-25
相关资源
最近更新 更多