为什么这个操纵器不能与-O3连接?

时间:2013-10-29 17:01:24

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

我定义了一个操纵器:

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

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

1 个答案:

答案 0 :(得分:1)

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