2013-05-20 3 views
3

xcode 4.6.2에서 clang ++를 사용하여 Mac OS X 10.8.3에서 "-std = C++ 11 -stdlib = libC++"로 프로그램을 컴파일하는 데 문제가 있습니다.clang ++ mac os x C++ 11 링커 문제

std :: mem_fn() 또는 (deprecated) std :: mem_fun_ref()를 사용하려고하면 링커 오류 "기호를 찾을 수 없습니다"가 나타납니다. 동일한 코드 (std :: mem_fn 대신 std :: mem_fun_ref 사용)는 C++ 03 표준에 따라 아무런 문제없이 컴파일하고 링크합니다.

mem_fn 또는 mem_fun_ref를 통해 객체를 참조하지 않고 동일한 멤버 함수를 호출하면 프로그램이 아무 문제없이 컴파일되고 실행됩니다. 그것은 clang ++ 문제입니까, Mac OS 문제입니까, 아니면 제가 잘못하고 있습니까?

코드 :

#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; 
} 

컴파일 로그 :

$ 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) 

답변

4

이 그 소리의 버그입니다. 나는 그것에 대한 버그 보고서를 찾을 수 없습니다. 버그 신고는 많은 도움이 될 것입니다.

string::empty은 "always_inline"으로 표시되지만 string 템플릿은 extern으로 표시되어 이미 인스턴스화되어 있습니다.

우리가이 조합을 가지고 있고 always_inline 멤버에 대한 멤버 함수 포인터를 만들면 어떤 이유로 clang은이를 가리킬 수 있도록 개요를 거부합니다. 인스턴스 생성이 extern으로 표시된 경우에만 거부합니다.

extern 또는 always_inline을 비활성화하면 코드가 작동합니다. "C++ 기타 플래그"에 이것을 포함 시키면 비활성화 할 수 있습니다.

-D'_LIBCPP_EXTERN_TEMPLATE(...)=' 
+0

답장을 보내 주셔서 감사합니다! 그것은 도왔다!) 불행히도, 제 영어 실력이 너무 좋지 않아서 버그 보고서를 제대로 작성하지 못했습니다. 그래서 당신이 할 수 있다면 - 멋진 것입니다 :) – Uniqus

+0

고마워요! 그것은 작동합니다. –