2015-01-02 14 views
7

Я столкнулся с интересной проблемой при попытке смешать clang (Apple LLVM version 6.0 (clang-600.0.56) (на основе LLVM 3.5svn, Target: x86_64-apple-darwin14.0.0), C++ 11 и CGAL (. через MacPorts)Является ли поддержка clang C++ 11 надежной?

кажется, что ли или не называть меня std::vector<>::reserve определит, будет ли моя программа даже компилировать

Я урезана проблема в минимальный пример (минимально примеры CGAL получить).:

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

издания:

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

Это не удается скомпилировать. Давать ошибки вроде:

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 == 

Однако это делает компилировать если я этот волшебный звонок std::vector::reserve, выдав:

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

или отключив C++ 11

clang++ -c example.cpp -I/opt/local/include 
  1. Это ошибка в CGAL или clang?
  2. Какое объяснение может возникнуть для такого неустойчивого поведения компилятора?
  3. Есть ли чистый способ избежать этого (надеюсь, без изменения шаблона шаблонов или функций, настроенных так, как мне нужно решение, чтобы соответствовать моему более крупному проекту).
+0

Это, по-видимому, случайность в определении Xcode 'is_convertible', но такая ошибка настолько невероятна, что мой разум отказывается принять ее существование. Есть ли у вас идеи, какая стандартная библиотека используется? Это другое, чем мой кланг. Я не знаю, что мое, но топ говорит: «Copyright (C) 2001-2013 Free Software Foundation, Inc.» –

+0

У Clang, похоже, есть libC++, у меня есть libstdC++ http://en.wikipedia.org/wiki/Standard_Template_Library#Implementations –

+0

Если я добавлю флаг '-stdlib = libC++', то ситуация не изменится.Вместо этого, если я добавлю '-stdlib = libstdC++', то никакая версия не компилируется, и я получаю такие ошибки, как' error: no template с именем 'forward' в пространстве имен 'std'; ' –

ответ

5

Поскольку GCC от Apple устарела (последняя версия GPL v2 версии 2007, GCC 4.2.1), а не C++ 11, полная (следовательно, предоставленная libstdC++), вы можете установить более современную версию GCC через MacPorts (sudo port install gcc48 или sudo port install gcc49), и это предоставит вам более современную версию libstdC++. Я проверил ваш код с:

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

И он скомпилирован успешно.

Если вы предпочитаете это решение и хотите, чтобы вызов компилятора был более чистым; Вы можете установить GCC MacPorts' в качестве значения по умолчанию, используя gcc_select с командой (в моем случае для gcc48):

sudo port select --set gcc mp-gcc48 

только один раз. Затем вы можете скомпилировать его только с

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

в новом терминале.

+0

Спасибо за объяснение. Это была моя типичная настройка, но теперь моя цель - заставить мой проект скомпилироваться со встроенным clang на mac: поэтому я не хочу переключать компиляторы. Какая особенность C++ 11 отсутствует в этом примере? –

+0

Спасибо. Рассматривая ваши комментарии в вопросе, похоже, что 'std :: forward' отсутствует, когда вы используете' libstdC++ 'от Apple. Длительный (но, надеюсь, полезный) способ состоит в том, чтобы игнорировать MacPorts и компилировать CGAL и все свои зависимости самостоятельно со встроенным clang. Я никогда не делал этого сам, и мне было бы интересно узнать о вашем опыте, если вы это сделаете. Альтернативой может быть сообщение об этих проблемах сторонникам MacPorts и ждать, пока они изменят сценарии компиляции CGAL и его зависимостей. – mty

+0

Спасибо. Итак, в конце концов, это ошибка в CGAL или ошибка в libstdC++ от Apple, которая каким-то образом натыкается на CGAL? –

Смежные вопросы