2015-01-02 13 views
7

Tôi gặp phải một vấn đề thú vị khi cố gắng trộn clang (Apple LLVM phiên bản 6.0 (clang-600.0.56) (dựa trên LLVM 3.5svn, Target: x86_64-apple-darwin14.0.0), C++ 11 và CGAL (. qua MacPorts)Hỗ trợ C++ 11 của clang có đáng tin cậy không?

dường như có hay không tôi gọi std::vector<>::reserve sẽ xác định xem chương trình của tôi thậm chí sẽ biên dịch

tôi đã cắt tỉa bớt những vấn đề thành một ví dụ rất nhỏ (càng ít càng CGAL ví dụ được).:

#include <vector> 
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h> 
#include <CGAL/AABB_tree.h> 
#include <CGAL/AABB_traits.h> 
#include <CGAL/AABB_triangle_primitive.h> 

// CGAL::Epeck works fine, suggesting the problem is in CGAL::Epick 
typedef CGAL::Epick Kernel; 
typedef CGAL::Triangle_3<Kernel> Triangle_3; 
typedef typename std::vector<Triangle_3>::iterator Iterator; 
typedef CGAL::AABB_triangle_primitive<Kernel, Iterator> Primitive; 
typedef CGAL::AABB_traits<Kernel, Primitive> AABB_triangle_traits; 
typedef CGAL::AABB_tree<AABB_triangle_traits> Tree; 
typedef typename Tree::Point_and_primitive_id Point_and_primitive_id; 
typedef CGAL::Point_3<Kernel> Point_3; 

template <typename BKernel> 
void A() 
{ 
    const CGAL::AABB_tree< 
    CGAL::AABB_traits<BKernel, 
     CGAL::AABB_triangle_primitive<BKernel, 
     typename std::vector<CGAL::Triangle_3<BKernel> >::iterator 
     > 
    > 
    > tree; 
    Point_and_primitive_id pp = tree.closest_point_and_primitive(Point_3()); 
} 

void B() 
{ 
    std::vector<Triangle_3> T; 
#ifdef MAGIC 
    T.reserve(0); 
#endif 
    return A<Kernel>(); 
} 

Cấp:

clang++ -std=c++11 -c example.cpp -I/opt/local/include 

Điều này không biên dịch được. lỗi Giving như:

In file included from example.cpp:1: 
    In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:265: 
    In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__bit_reference:15: 
    In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/algorithm:626: 
    In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/utility:157: 
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__tuple:228:60: error: 
      no member named 'value' in 'std::__1::is_convertible<const CGAL::Point_3<CGAL::Epick> &, 
      CGAL::Point_3<CGAL::Epick> >' 
            is_convertible<_Tp0, _Up0>::value && 
            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ 

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__tuple:242:14: note: 
      in instantiation of template class 'std::__1::__tuple_convertible_imp<true, std::__1::__tuple_types<const 
      CGAL::Point_3<CGAL::Epick> &, const CGAL::Vector_3<CGAL::Epick> &>, 
      std::__1::__tuple_types<CGAL::Point_3<CGAL::Epick>, CGAL::Vector_3<CGAL::Epick> > >' requested here 
     : public __tuple_convertible_imp<tuple_size<typename remove_reference<_Tp>::type>::value == 

Tuy nhiên, này không biên dịch nếu tôi thực hiện cuộc gọi kỳ diệu này để std::vector::reserve, phát hành:

clang++ -std=c++11 -c example.cpp -I/opt/local/include -DMAGIC 

hoặc bằng cách tắt C++ 11

clang++ -c example.cpp -I/opt/local/include 
  1. Đây có phải là lỗi trong CGAL hoặc tiếng kêu không?
  2. Có thể giải thích cho hành vi trình biên dịch thất thường như thế nào?
  3. Có cách nào làm sạch cách tránh điều này (hy vọng mà không thực sự thay đổi mẫu thử hoặc chức năng được thiết lập khi tôi cần giải pháp để phù hợp với dự án lớn hơn của tôi).
+0

Điều này có vẻ là một lỗi trong định nghĩa XCode của 'is_convertible', nhưng có một lỗi như vậy là không thể xảy ra mà tâm trí của tôi từ chối chấp nhận sự tồn tại của nó. Bạn có bất kỳ ý tưởng mà thư viện chuẩn đang được sử dụng? Nó khác với tiếng kêu của tôi đang sử dụng. Tôi không biết cái gì là của tôi nhưng phần đầu nói "Bản quyền (C) 2001-2013 Free Software Foundation, Inc." –

+0

Clang dường như có libC++, wheras Tôi có libstdC++ http://en.wikipedia.org/wiki/Standard_Template_Library#Implementations –

+0

Nếu tôi thêm cờ '-stdlib = libC++' thì tình huống sẽ không thay đổi.Thay vào đó, nếu tôi thêm '-stdlib = libstdC++' thì không biên dịch phiên bản nào và tôi gặp lỗi như 'error: không có mẫu nào có tên 'forward' trong namespace 'std'; ' –

Trả lời

5

Vì GCC của Apple đã lỗi thời (phiên bản GPL v2 mới nhất từ ​​năm 2007, GCC 4.2.1) và không hoàn thành tính năng C++ 11 (do đó libstdC++ được cung cấp), bạn có thể cài đặt phiên bản GCC mới hơn thông qua MacPorts (sudo port install gcc48 hoặc sudo port install gcc49) và điều đó sẽ cung cấp cho bạn phiên bản libstdC++ hiện đại hơn. Tôi đã thử nghiệm mã của bạn với:

/opt/local/bin/g++-mp-4.8 -std=c++11 -c example.cpp -I/opt/local/include 

và được biên dịch thành công.

Nếu bạn thích giải pháp này và muốn có cuộc gọi trình biên dịch rõ ràng hơn; bạn có thể đặt GCC MacPorts' như là mặc định sử dụng gcc_select với lệnh (trong trường hợp của tôi cho gcc48):

sudo port select --set gcc mp-gcc48 

chỉ một lần. Sau đó, bạn có thể biên dịch nó chỉ với

g++ -std=c++11 -c example.cpp -I/opt/local/include 

trong phiên thiết bị đầu cuối mới.

+0

Cảm ơn lời giải thích. Đây là thiết lập điển hình của tôi, nhưng mục tiêu của tôi bây giờ là để có được dự án của tôi để biên dịch với xây dựng trong clang trên mac: vì vậy tôi không muốn chuyển đổi trình biên dịch. Tính năng nào của C++ 11 bị thiếu trong ví dụ này? –

+0

Cảm ơn bạn. Nhìn nhận xét của bạn trong câu hỏi, có vẻ như 'std :: forward' bị thiếu khi bạn sử dụng' libstdC++ 'của Apple. Cách dài (nhưng hy vọng bổ ích) sẽ được bỏ qua MacPorts và biên dịch CGAL và tất cả các phụ thuộc của nó cho mình với clang tích hợp. Tôi không bao giờ làm điều này bản thân mình và tôi sẽ được quan tâm để đọc về kinh nghiệm của bạn nếu bạn làm điều đó. Một giải pháp thay thế có thể là báo cáo những vấn đề này cho những người bảo trì MacPorts và chờ họ thay đổi các kịch bản biên dịch của CGAL và các phụ thuộc của nó. – mty

+0

Cảm ơn. Vì vậy, cuối cùng là một lỗi trong CGAL hoặc một lỗi trong libstdc của Apple + + mà CGAL là bằng cách nào đó ngại? –

Các vấn đề liên quan