0

I have a manipulator defined:

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

Which I am using like so:

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

All of this compiles just fine using Boost.bjam in both debug and release mode. However, when it comes time to link I get the following error in release mode only:

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)

Or, more legibly:

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)

If I comment out the manipulator, everything compiles and links just fine in both debug and release modes.

If I leave in the manipulator I can work around the linker error by rebuilding the project with -O0, however I would prefer it if my release mode were the bjam default (-O3).

I am running Xcode 4.6.2 and its associated 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

How do I get this manipulator to link properly with optimizations on?

fbrereto
  • 35,429
  • 19
  • 126
  • 178
  • It seems that a lot of people have started getting linker errors after updating to Mavericks... Does this SO post help:?http://stackoverflow.com/questions/19550436/how-mavericks-xcode5-0-1-changed-the-compiler-and-linker – AndyG Oct 29 '13 at 17:02
  • @AndyG: Thanks for the link, unfortunately it seems unrelated. Linking with `-O0` compiled sources produces no error, so I am able to get *something* to link. What's more I'm still running 10.8.5 and Xcode 4.6.2. – fbrereto Oct 29 '13 at 17:12

1 Answers1

1

Drop the inline. I suspect you have the manipulator declared in some header and only defined in one translation unit? With inline you are changing the symbol's visibility and that probably means the compiler generated the function but it is not exporting the symbol so that the other translation units can see it, i.e., the linker doesn't find it.

Daniel Frey
  • 55,810
  • 13
  • 122
  • 180
  • If I drop the inline I get duplicate symbol errors (I am using this manipulator in more than one translation unit.) Making it `static` seems to have resolved the issue. Thanks! – fbrereto Oct 29 '13 at 17:28
  • Sorry, I closed this one out too early. Removing the inline did not fix the problem, nor did adding (or removing) the `static` qualifier. I also templatized the routine to take a `basic_ostream` and the linker error remains. – fbrereto Oct 29 '13 at 17:44
  • @fbrereto Care to edit your question and add the *real* code then? – Daniel Frey Oct 29 '13 at 17:48
  • In the midst of doing as you asked, I realized I had not tried removing the `inline` and then moving the code bodies out of the header and into a source file, eliminating the duplicate symbol errors. That seems to have fixed things for good. Thanks! – fbrereto Oct 29 '13 at 17:55