2014-03-03 6 views
0

MacBook에 GDL을 설치하기 위해 싸우고 있습니다. 10.9.2와 컴파일 할 때 많은 문제가있었습니다.OS X 비법 컴파일시 모호한 함수

/Downloads/gdl-0.9.4/src/basic_fun.cpp:6415:14: error: call to 'isalpha' is ambiguous 
     if (!isalpha(*p) && !isdigit(*p) && *p != '+' && *p != '.' && *p != '-') 
      ^~~~~~~ 
/usr/include/ctype.h:218:1: note: candidate function 
isalpha(int _c) 
^ 
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/cctype:60:38: note: 
     candidate function 
inline _LIBCPP_INLINE_VISIBILITY int isalpha(int __c) {return __libcpp_isalpha(__c);} 

가 그들은 쉽게 ::foo()foo()을 변경하여 고정하고 있지만 그것은 조금 해키 보인다 결국 나는 형태의 문제를 많이 후 관리. Homebrew가 wxmac와 같은 것을 설치해도 문제는 계속됩니다. 모호한 함수에 동일한 문제가 발생하도록 헤더 중 하나를 변경해야했습니다. 흥미롭게도 문제가 발생하지 않습니다 isdigit() - 의미가 있습니까?

Xcode의 libC++와/usr/include의 헤더 사이에 문제가있는 것 같습니다. 이 문제를 해결하는 간단한 방법이 있습니까?

내 여자 친구의 Mountain Lion 컴퓨터에서 GDL을 컴파일 할 때 이것은 문제가되지 않았습니다.

+0

최소 테스트 케이스? XCode Tools 명령 줄을 사용하여 재현 할 수 없습니다. cmake .. -DREADLINEDIR =/usr/지방/셀라/readline에/6.2.4/-DHDF = OFF -DCMAKE_BUILD_PREFIX =/usr/지방/GD 만들기 : 그것은에서 온다 – Potatoswatter

+0

약간 하드는 테스트 케이스를 제공합니다 여러개의 파일을 컴파일 할 때 실패합니다. 실패 할 첫 번째 파일은 보통 basic_fun.cpp입니다. 나머지 컴파일 오류는 동일하지만 tolower(), toupper(), isalpha(), isspace()를 사용하면 동일합니다. wxmac의 오류는 wchar fuction입니다. 또한 "gdl-0.9.4/src/gsl_fun.cpp : 3892 : 9 : error : 실행 가능 오버로드가 없습니다 '* ='"로 명시 적 캐스트로 수정했습니다. 이 방법으로 오류가있는 샘플 cpp 파일을 노크하려고합니다. – Josh

답변

2

확실치는 않지만,이 경우에는 내가 쫓고있는 문제인 것처럼 보입니다.이 경우에는 tolower()를 사용합니다. 필자는 isalpha(), tolower() 등의 다양한 문자 처리 루틴에 대한 매크로를 정의하는 헤더를 포함하고 있다고 생각합니다. 필자의 경우에는 이것이 Boost 코드에 포함 된 Python 포함 파일 pyport.h입니다. 다음에 일어나는 일은 매우 복잡하지만 다음 작업 중 하나를 수정해야합니다.

  • 'namespace std'문을 제거하십시오.
  • 사용 :: tolower() 등
  • std :: tolower() 등을 사용하면 효과가 있지만 올바르게 작동하지 않습니다.
  • include 문을 다시 정렬하면 tolower() 등을 매크로로 정의하는 pyport.h와 같이
    과 같이 앞에 cctype이 포함됩니다.
  • # 가능한 한 코드의 초기에 #include cctype을 넣기 만하면됩니다.

다음은 내가 쓴 문제에 대한 기사를 썼다. 정확히 당신의 문제가 아니더라도 그것이 확실히 관련되어있는 것처럼 들립니다.

기본적으로 다음 예제 프로그램은 부스트가 설치되어 있고 Python 2.7을 실행중인 요세미티 시스템에서 컴파일하지 않습니다. 다른 Python 버전을 사용하는 다른 OS X 머신도 괜찮습니다.

#include <boost/python.hpp> 
#include <boost/asio/ssl.hpp> 

int main() { 
    return 0; 
} 

'tolower'가 모호하다는 오류 메시지가 2 번 표시됩니다. 두 오류는 기본적으로 동일하며 다음과 같이 :

In file included from demo1.cpp:3: 
In file included from /usr/local/include/boost/asio/ssl.hpp:23: 
In file included from /usr/local/include/boost/asio/ssl/rfc2818_verification.hpp:99: 
/usr/local/include/boost/asio/ssl/impl/rfc2818_verification.ipp:146:14: error: 
     call to 'tolower' is ambiguous 
    else if (tolower(*p) == tolower(*h)) 

/usr/include/ctype.h:292:1: note: candidate function 
tolower(int _c) 

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/cctype:149:38: note: 
     candidate function 
inline _LIBCPP_INLINE_VISIBILITY int tolower(int __c) {return __libcpp_t... 

이유는 매우 복잡하지만, 근본적인 문제는 파이썬이 tolower를 같이 처리 루틴을 다양한 문자()와 함께 놨 pyport.h 파일을 포함하는 방법에서 비롯됩니다. 기본적으로 tolower()를 매크로로 재정 의하여 문자 너비 관련 문제를 해결합니다. 이 매크로는 표준 cctype include 파일이 tolower()를 처리하는 방법을 혼동합니다. 결과는 전역 네임 스페이스에서 tolower()이고 std 네임 스페이스에서 다른 하나가됩니다. tolower()가 'using namespace std'가 적용되는 범위에서 사용되면 문제가 마침내 나타납니다.

위의 예는 문제를 유발하는 최소한의 코드로 축소되었습니다. pyport.h 파일에는 ctype.h 및 wctype.h가 포함되어 있으며 tolower()에 #define이 있습니다. 그 다음에 오는 코드는 wchar을 포함하여 문제를 일으키는 일종의 문제입니다.h 및 cctype을 사용하고 'using namespace std'및 tolower()에 대한 참조를 사용합니다 (이는 Boost, rfc2818_verification.ipp와 동일하지만 동일한 코드는 문제를 유발합니다).

여기서는 어떻게됩니까? 문제는 기본적으로 pyport.h가 tolower()가 매크로로 정의 될 때 tolower()가 cctype include 파일을 처리하는 방식과 결합 된 tolower()를 매크로로 정의한다는 것입니다.

pyport.h는 파이썬이 넓은 문자에서 작동하는 최신 버전의 tolower() 등으로 인해 문제를 해결하려고 시도하고 있습니다. tolower()를 좁은 문자에서 명시 적으로 작동하는 매크로로 정의하여이 문제를 해결합니다. 그리고 이것은 대부분의 시간 동안 작동합니다.

cctype은 실제 루틴과는 달리 일반 tolower() 루틴이 단순히 매크로로 정의 된 시스템에서 발생하는 일을 처리하려고합니다. 이 경우 std ::에서 루틴을 정의합니다. tolower()가 매크로를 사용하여 수행하고 매크로를 대체합니다. 그것이 무엇을하는 것은 기본적으로 :

tolower를 정상적인 글로벌 네임 스페이스에 불과 루틴 기계에
_LIBCPP_BEGIN_NAMESPACE_STD 

#ifdef tolower 
inline _LIBCPP_INLINE_VISIBILITY int __libcpp_tolower(int __c) {return tolower(__c);} 
#undef tolower 
inline _LIBCPP_INLINE_VISIBILITY int tolower(int __c) {return __libcpp_tolower(__c);} 
#else // tolower 
using ::tolower; 
#endif // tolower 

_LIBCPP_END_NAMESPACE_STD 

, 그것은 단순히 '사용 : tolower를'을 발행합니다. 이것은 OS X의 일반적인 경우입니다.

이 모든 경우에 문제가 발생하는 방식은 cctype이 포함 된 시점에서 tolower()가 매크로로 정의되었지만 사적인 목적으로 발생합니다 파이썬을 정의하는 일반적인 방법이기 때문에가 아니라. 그 결과 전역 네임 스페이스 (정상적인 방법으로 ctype.h로 정의)에서 tolower()와 std :: namespace에서 tolower() (cctype에 의해 정의 됨, 이는 pyport로 선언 된 매크로 정의에 속아 왔습니다.) .h.)

정상적인 전역 tolower()를 선택하므로 명시 적 네임 스페이스가없는 tolower()를 사용하면 문제가되지 않습니다. std :: tolower() 또는 :: tolower()를 명시 적으로 사용하면 문제가 없으므로 아무 문제가 없습니다. 'namespace std'를 사용하고 나서 tolower()를 사용하면 문제가됩니다. tolower를 std에서 볼 수있는 컴파일러에게 말했기 때문에 tolower()를 사용하면 그렇게 할 수 있습니다. 그러나 정상적인 전역 tolower()도 찾을 수 있습니다. 그리고 나서 그것은 무엇을 해야할지 모르고 당신의 잘못이 있습니다.

수정 방법은 무엇입니까?

문제가 코드에서 나타나는지 또는 코드를 부스트 할 수 있는지 (Boost 포함 파일과 같거나 같을 수는 없다)에 따라 달라집니다. 코드를 변경할 수있는 경우 :

o 'using namespace std;'를 사용하지 마십시오. 어쨌든 좋은 생각이 아닙니다.

o :: tolower()를 사용하십시오. 그렇다면 애매 모호하지 않습니다.

o std :: tolower()를 사용합니다. cctype이이를 정의 할 때만 작동합니다. 일반적으로 그렇지 않습니다. 문제를 트리거 코드 파일을 변경할 수없는 경우

는 :

O를 다시 순서를 cctype이 pyport.h을 포함하는 하나의 전에 포함 무엇 때문에이 파일이 포함됩니다. 그런 다음 cctype은 tolower()의 정의를 매크로로 보지 않으며 모두 잘 작동합니다.

o #include cctype을 가능한 한 코드의 초기에 넣으십시오. 그렇다면 pyport.h가 일을 혼란스럽게 만들기 전에 다루어지고, 이후의 모든 것들은 무시 될 것이다. 그것은 모두의 가장 간단한 해결일지도 모른다.