Reputation: 574
I have a problem compiling a program with "-std=c++11 -stdlib=libc++" under mac os x 10.8.3 using clang++ from xcode 4.6.2.
When I try to use std::mem_fn() or (deprecated) std::mem_fun_ref(), I get linker error "symbol(s) not found". The same code (with std::mem_fun_ref instead of std::mem_fn) compiles and links without any issues under the c++03 standard.
If I call the same member function on an object without referring to it via mem_fn or mem_fun_ref, the program compiles and runs without any problems. Is it a clang++ problem, a mac os problem, or am I doing something wrong?
The code:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int main(int argc, char **arvc)
{
/* The beginning of the function compiles without any errors */
string str = "It's a test)";
if (str.empty())
{
cout << "String is empty!!!" << endl;
}
vector<string> v1;
v1.push_back("str1");
v1.push_back("str2");
v1.push_back("");
v1.push_back("str4");
v1.push_back("");
v1.push_back("str6");
/* The code after this point leads to linker error */
vector<string>::iterator it = remove_if(v1.begin(), v1.end(), mem_fn(&string::empty));
v1.erase(it, v1.end());
for (it = v1.begin(); it < v1.end(); ++it)
{
cout << " '" << *it << "'" << endl;
}
return 0;
}
The compilation log:
$ xcrun clang++ -v -std=c++11 -stdlib=libc++ ../src/test_cxx.cpp
Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn)
Target: x86_64-apple-darwin12.3.0
Thread model: posix
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang" -cc1 -triple x86_64-apple-macosx10.8.0 -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -main-file-name test_cxx.cpp -pic-level 2 -mdisable-fp-elim -masm-verbose -munwind-tables -target-cpu core2 -target-linker-version 136 -v -resource-dir /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/4.2 -isysroot / -fmodule-cache-path /var/folders/nz/0x05d6p14gddzxxn8ymnn74c0000gn/T/clang-module-cache -stdlib=libc++ -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /Volumes/Work/projects/web/sp3/build -ferror-limit 19 -fmessage-length 80 -stack-protector 1 -mstackrealign -fblocks -fobjc-runtime=macosx-10.8.0 -fobjc-dispatch-method=mixed -fobjc-default-synthesize-properties -fcxx-exceptions -fexceptions -fdiagnostics-show-option -fcolor-diagnostics -o /var/folders/nz/0x05d6p14gddzxxn8ymnn74c0000gn/T/test_cxx-kAQ3wk.o -x c++ ../src/test_cxx.cpp
clang -cc1 version 4.2 based upon LLVM 3.2svn default target x86_64-apple-darwin12.3.0
ignoring nonexistent directory "/usr/include/c++/v1"
#include "..." search starts here:
#include <...> search starts here:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1
/usr/local/include
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/4.2/include
/usr/include
/System/Library/Frameworks (framework directory)
/Library/Frameworks (framework directory)
End of search list.
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld" -demangle -dynamic -arch x86_64 -macosx_version_min 10.8.0 -syslibroot / -o a.out /var/folders/nz/0x05d6p14gddzxxn8ymnn74c0000gn/T/test_cxx-kAQ3wk.o -lc++ -lSystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/4.2/lib/darwin/libclang_rt.osx.a
Undefined symbols for architecture x86_64:
"std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::empty() const", referenced from:
_main in test_cxx-kAQ3wk.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Upvotes: 3
Views: 1731
Reputation: 219478
This is a bug in clang. I can't find a bug report on it though. A bug report would be much appreciated.
The problem is that string::empty
is marked "always_inline", but also the string
template is marked extern, meaning that it has been instantiated already for you.
For some reason when we have this combination, and you form a member function pointer to the always_inline member, clang refuses to outline it so that it can point to it. It only refuses if the instantiation is marked as extern.
If you disable either the extern, or the always_inline, then the code will work. You can disable the former by including this in "C++ Other Flags":
-D'_LIBCPP_EXTERN_TEMPLATE(...)='
Upvotes: 5