2012-03-06 2 views
1

Я пытался скомпилировать код, использующий Boost (1.49), с Clang (libC++) из багажника. Проблемный код сводится к следующему:неявное создание неопределенного шаблона: Boost Bug или Clang Bug?

#include <memory> 
#include <boost/signals2.hpp> 

int main() 
{ 
    std::shared_ptr<int> s; 
} 

При компиляции с Clang, следующее сообщение emmited:

$ clang++ -I/home/alexander/usr/local/include --stdlib=libc++ -std=c++0x signals2-bug.cpp -o signals2-bug 
signals2-bug.cpp:6:26: error: implicit instantiation of undefined template 
     'std::shared_ptr<int>' 
    std::shared_ptr<int> s; 
         ^
/home/alexander/usr/local/include/boost/signals2/detail/foreign_ptr.hpp:24:30: note: 
     template is declared here 
    template<typename T> class shared_ptr; 
         ^

обижая линии в повышающем/signals2/Detail/foreign_ptr.hpp являются:

#if !defined(BOOST_INTEL_STDCXX0X) 
namespace std 
{ 
    template<typename T> class shared_ptr; 
    template<typename T> class weak_ptr; 
} 
#endif 

Теперь, кто виноват?

Две вещи приходят на ум:

  1. Почему Boost.Signals заголовка чувствуют необходимость объявить собственный shared_ptr? Какой выигрыш?
  2. Линия в Boost.Signals выглядит как простая декларация. Почему это будет проблематично, если это произойдет после определения шаблона?

EDIT

Это, как представляется, ошибка Boost.Signals2, потому что объявление вещей в станд :: результаты пространств имен в неопределенном поведении, в соответствии с разделом ISO/IEC C++ 2011 Standard 17.6.4.2.1:

поведение программы на C++ не определен, если он добавляет декларации или определений патезрасе или к пространству имен в пространстве имен станд , если не указано иное. Программа может добавить шаблон специализация для любого стандартного шаблона библиотеки в пространство имен std, только если декларация зависит от пользовательского типа , и специализация соответствует стандартным требованиям библиотеки для исходного шаблона и явно не указывается .

Билет в подталкивания багтрекер была создана: https://svn.boost.org/trac/boost/ticket/6655

Пожалуйста, обратите внимание, что ошибка Clang также существует здесь: http://llvm.org/bugs/show_bug.cgi?id=10521, однако точки Implementor нарушения.

Последующие для Googlers:

Проблема была действительно подталкивания ошибка. Это changeset 77289 должно исправить проблему для Boost 1.50. Соответствующая ошибка в Clang была отмечена как недопустимая.

+3

Похож на довольно четкую ошибку в Boost.Signals2 для меня. – ildjarn

+0

@ildjarn: не должно быть проблем с * объявлением * шаблонов, если библиотека boost не пытается * определить * их. Ошибка, похоже, говорит о том, что определения нет вообще - видимо, в том числе '' не определял 'std :: shared_ptr', как ожидалось. –

+0

@Mike: В самом деле, однако, '# if' в коде Boost явно неправильный (или, по крайней мере, менее идеальный). – ildjarn

ответ

-1

Код в foreign_ptr.hpp является переопределение (если shared_ptr уже определен), и как таковые не могут вызвать проблемы (добавление деклараций к std технически неопределенное поведение, но большинство компиляторов не волнует, так как они не делают действительно различают стандартные заголовки библиотек и другие файлы). Таким образом, ошибка может быть вызвана только тем, что shared_ptr фактически не определено.

В настоящее время libc++, очевидно, имеет определение shared_ptr, поэтому я могу только заподозрить, что некоторые библиотеки C++ 03 внесли его в путь включения каким-то образом и получили преимущество над libC++.

+0

Хорошая идея, но я проверил пути включения (с ключом -v), и нет другого заголовка перед тем, как из libC++. –

+0

Я думаю, что ключевым моментом является то, что это неопределенное поведение! Стандарт упоминает его в 17.6.4.2.1. Я отредактирую, чтобы объяснить и сообщить об ошибке с Boost.Signals2. –

+0

Этот ответ неверен. Ошибка связана с libC++ объявлением shared_ptr в встроенном пространстве имен, вложенном в std, и дистально вызван неопределенным поведением кода повышения. –