2015-07-14 10 views
8

Ho visto crash nel nostro software da quando ho aggiornato per aumentare 1.58 e VS2013. Solo quando l'ottimizzazione del compilatore è attiva vediamo che si blocca. Con la spinta 1.55 non ci sono arresti anomali. Sono riuscito a isolare il problema che sto vedendo a boost::any_range e come lo usiamo.Si tratta di un bug di ottimizzazione C++ di aggiornamento di Visual Studio 2013 4 o il mio codice è errato?

vedere il codice esempio riportato di seguito:

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

Di seguito è riportato l'output del programma. La versione debug è quello che mi aspetto, ma la versione ottimizzata è un mistero per me in questo momento ...

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 

Forse il mio codice è sbagliato o è davvero un bug nel ottimizzatore? Qualsiasi consiglio sarebbe molto apprezzato!

+2

'_ContainerType' è un nome riservato (perché inizia con un trattino basso seguito da una lettera maiuscola). Non correlato al tuo problema, però. – dyp

+2

Non sembra un bug del compilatore: http://coliru.stacked-crooked.com/a/edcdb838034085ca – dyp

+3

Si prega di presentare un banco di prova minimamente compilabile. Avrebbe una funzione 'main'. Inoltre ... accendi gli avvisi del compilatore !!!!!!!!!!!!!! –

risposta

11

Questo è Boost bug 10493 (introdotto in Boost 1.56, motivo per cui il codice funziona con Boost 1.55).

La soluzione è utilizzare T const come parametro Reference modello, nel tuo caso:

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

Example.

+0

Grazie mille a tutti per aver esaminato questo e per le vostre risposte e suggerimenti! – Jormungand999