2015-07-14 1 views
8

Я видел сбои в нашем программном обеспечении, так как обновлялся, чтобы увеличить 1.58 и VS2013. Только когда оптимизация компилятора включена, мы видим, что сбои. С boost 1.55 никаких сбоев нет. Мне удалось изолировать проблему, которую я вижу до boost::any_range и как мы ее используем.Является ли обновление Visual Studio 2013 4 ошибкой оптимизатора C++ или неправильным кодом?

Смотрите пример кода ниже:

#include <boost/range/any_range.hpp> 
#include <boost/range/adaptor/transformed.hpp> 
#include <vector> 
#include <memory> 
#include <cstdio> 

class DummyElement 
{ 
public: 
    float f_; 
}; 

using ElementRange = boost::any_range < DummyElement*, boost::bidirectional_traversal_tag >; 

using DummyElementUPtr = std::unique_ptr <DummyElement> ; 

class BoostAnyTest 
{ 
public: 
    BoostAnyTest() 
    { 
     for (int i = 0; i < 10; ++i) 
     { 
      auto element = DummyElementUPtr(new DummyElement()); 
      _tprintf(_T("BoostAnyTest::ctor() 0x%p\n"), element.get()); 

      c_.emplace_back(std::tuple<Int, DummyElementUPtr>(i, std::move(element))); 
     } 
    } 

public: 
    ElementRange GetAll(); 

private: 
    using _ContainerType = std::vector < std::tuple<Int, std::unique_ptr<DummyElement>> > ; 
    _ContainerType c_; 
}; 


ElementRange 
BoostAnyTest::GetAll() 
{ 
    auto transform = [ ] (const _ContainerType::value_type& v) -> DummyElement* 
    { 
     return std::get<1>(v).get(); 
    }; 

    return c_ | boost::adaptors::transformed(transform); 
} 


int 
main() 
{ 
    BoostAnyTest any; 

    auto range = any.GetAll(); 

    std::for_each(std::begin(range), std::end(range), [ ] (DummyElement* element) 
    { 
     _tprintf(_T("TestBoostAnyRange() 0x%p\n"), element); 
    }); 
} 

Ниже приводится вывод программы. Версия отладочной то, что я ожидал, но оптимизированная версия RELEASE является загадкой для меня на данный момент ...

DEBUG version output: 
BoostAnyTest::ctor() 0x007D0FB0 
BoostAnyTest::ctor() 0x007D0E30 
BoostAnyTest::ctor() 0x007D0E60 
BoostAnyTest::ctor() 0x007D1160 
BoostAnyTest::ctor() 0x007D0E90 
BoostAnyTest::ctor() 0x007D10A0 
BoostAnyTest::ctor() 0x007D0F80 
BoostAnyTest::ctor() 0x007D0FE0 
BoostAnyTest::ctor() 0x007D1010 
BoostAnyTest::ctor() 0x007D1040 
TestBoostAnyRange() 0x007D0FB0 
TestBoostAnyRange() 0x007D0E30 
TestBoostAnyRange() 0x007D0E60 
TestBoostAnyRange() 0x007D1160 
TestBoostAnyRange() 0x007D0E90 
TestBoostAnyRange() 0x007D10A0 
TestBoostAnyRange() 0x007D0F80 
TestBoostAnyRange() 0x007D0FE0 
TestBoostAnyRange() 0x007D1010 
TestBoostAnyRange() 0x007D1040 

RELEASE version output: 
BoostAnyTest::ctor() 0x00BFA358 
BoostAnyTest::ctor() 0x00BFA238 
BoostAnyTest::ctor() 0x00BFA3E8 
BoostAnyTest::ctor() 0x00BFA248 
BoostAnyTest::ctor() 0x00BFA258 
BoostAnyTest::ctor() 0x00BFA268 
BoostAnyTest::ctor() 0x00C2ECB8 
BoostAnyTest::ctor() 0x00C2ED98 
BoostAnyTest::ctor() 0x00C2EDA8 
BoostAnyTest::ctor() 0x00C2ED48 
TestBoostAnyRange() 0x00A5FCE0 
TestBoostAnyRange() 0x00A5FCE0 
TestBoostAnyRange() 0x00A5FCE0 
TestBoostAnyRange() 0x00A5FCE0 
TestBoostAnyRange() 0x00A5FCE0 
TestBoostAnyRange() 0x00A5FCE0 
TestBoostAnyRange() 0x00A5FCE0 
TestBoostAnyRange() 0x00A5FCE0 
TestBoostAnyRange() 0x00A5FCE0 
TestBoostAnyRange() 0x00A5FCE0 

Может быть, мой код неправильно, или это действительно ошибка в оптимизатора? Любые советы будут очень признательны!

+2

'_ContainerType' - зарезервированное имя (потому что оно начинается с подчеркивания, за которым следует заглавная буква). Тем не менее, это не связано с вашей проблемой. – dyp

+2

Не похож на ошибку компилятора: http://coliru.stacked-crooked.com/a/edcdb838034085ca – dyp

+3

Просьба представить скомпилированный минимальный тестовый файл. Он будет иметь функцию «main». Также ... включите свои предупреждения компилятора !!!!!!!!!!!!!! –

ответ

11

Это Boost bug 10493 (введено в Boost 1.56, поэтому ваш код работает с Boost 1.55).

Для устранения этой проблемы использовать T const в качестве параметра Reference шаблона, в вашем случае:

using ElementRange = boost::any_range < 
    DummyElement*, 
    boost::bidirectional_traversal_tag, 
    DummyElement* const 
>; 

Example.

+0

Спасибо всем за то, что заглянули в это и за ваши ответы и предложения! – Jormungand999

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