2012-05-15 3 views
4

Следующий сегмент кода вводит бесконечный цикл внутри оператора BOOST_FOREACH, и я не могу понять, почему. Насколько мне известно, из документации Boost следует использовать «break» внутри цикла BOOST_FOREACH. Любая идея, что здесь может быть неправильным?BOOST_FOREACH вводит бесконечный цикл при использовании «break»?

std::vector<std::wstring> sectors = getSectors(); 
if (!_sectorCodes.empty()) { // _sectorCodes is a std::set<std::wstring>. 
    bool ok = false; // did we find the sector code we wanted? 
    BOOST_FOREACH(Symbol sector, sectors) { 
     if (_sectorCodes.find(sector) != _sectorCodes.end()) { 
      ok = true; 
      break; 
     } 
    } 
    if (!ok) return NULL; 
} 

Если я заменю цикл BOOST_FOREACH с цикл (с использованием итератора от sectors.begin() до sectors.end()), то она работает просто отлично (без бесконечный цикл).

Версия & Дополнительная информация:

  • подталкивание: 1.40.0
  • НКУ: 4.1.2
  • архитектура: x86_64
  • я только получаю это поведение для версии релиза; если я создаю отладочную сборку, то она работает так, как ожидалось.
  • При компиляции под визуальную студию он работает как ожидалось, т. Е. Без бесконечного цикла.

В ответ на вопрос MKB, вот что я получаю, когда я бегу gcc -E:

if (!_sectorCodes.empty()) { 
bool ok = false; 
if (boost::foreach_detail_::auto_any_t _foreach_col148 = boost::foreach_detail_::contain((sectors) , (true ? 0 : boost::foreach_detail_::or_(boost::foreach_detail_::and_(boost::foreach_detail_::not_(boost::foreach_detail_::is_array_(sectors)) , (true ? 0 : boost::foreach_detail_::is_rvalue_((true ? boost::foreach_detail_::make_probe(sectors) : (sectors)), 0))) , boost::foreach_detail_::and_(boost::foreach_detail_::not_(boost_foreach_is_noncopyable(boost::foreach_detail_::to_ptr(sectors) , boost_foreach_argument_dependent_lookup_hack_value)) , boost_foreach_is_lightweight_proxy(boost::foreach_detail_::to_ptr(sectors) , boost_foreach_argument_dependent_lookup_hack_value)))))) {} else if (boost::foreach_detail_::auto_any_t _foreach_cur148 = boost::foreach_detail_::begin(_foreach_col148 , (true ? 0 : boost::foreach_detail_::encode_type(sectors, boost::foreach_detail_::is_const_(sectors))) , (true ? 0 : boost::foreach_detail_::or_(boost::foreach_detail_::and_(boost::foreach_detail_::not_(boost::foreach_detail_::is_array_(sectors)) , (true ? 0 : boost::foreach_detail_::is_rvalue_((true ? boost::foreach_detail_::make_probe(sectors) : (sectors)), 0))) , boost::foreach_detail_::and_(boost::foreach_detail_::not_(boost_foreach_is_noncopyable(boost::foreach_detail_::to_ptr(sectors) , boost_foreach_argument_dependent_lookup_hack_value)) , boost_foreach_is_lightweight_proxy(boost::foreach_detail_::to_ptr(sectors) , boost_foreach_argument_dependent_lookup_hack_value)))))) {} else if (boost::foreach_detail_::auto_any_t _foreach_end148 = boost::foreach_detail_::end(_foreach_col148 , (true ? 0 : boost::foreach_detail_::encode_type(sectors, boost::foreach_detail_::is_const_(sectors))) , (true ? 0 : boost::foreach_detail_::or_(boost::foreach_detail_::and_(boost::foreach_detail_::not_(boost::foreach_detail_::is_array_(sectors)) , (true ? 0 : boost::foreach_detail_::is_rvalue_((true ? boost::foreach_detail_::make_probe(sectors) : (sectors)), 0))) , boost::foreach_detail_::and_(boost::foreach_detail_::not_(boost_foreach_is_noncopyable(boost::foreach_detail_::to_ptr(sectors) , boost_foreach_argument_dependent_lookup_hack_value)) , boost_foreach_is_lightweight_proxy(boost::foreach_detail_::to_ptr(sectors) , boost_foreach_argument_dependent_lookup_hack_value)))))) {} else for (bool _foreach_continue148 = true; _foreach_continue148 && !boost::foreach_detail_::done(_foreach_cur148 , _foreach_end148 , (true ? 0 : boost::foreach_detail_::encode_type(sectors, boost::foreach_detail_::is_const_(sectors)))); _foreach_continue148 ? boost::foreach_detail_::next(_foreach_cur148 , (true ? 0 : boost::foreach_detail_::encode_type(sectors, boost::foreach_detail_::is_const_(sectors)))) : (void)0) if (boost::foreach_detail_::set_false(_foreach_continue148)) {} else for (Symbol sector = boost::foreach_detail_::deref(_foreach_cur148 , (true ? 0 : boost::foreach_detail_::encode_type(sectors, boost::foreach_detail_::is_const_(sectors)))); !_foreach_continue148; _foreach_continue148 = true) { 
    if (_sectorCodes.find(sector) != _sectorCodes.end()) { 
    ok = true; 
    break; 
    } 
} 
if (!ok) return PatternFeatureSet_ptr(); 
} 

Одной примечательной особенностью этого расширения является то, что есть два вложенных для петель. Я не могу понять, что происходит во внутренних и внешних циклах, но возможно ли, что (как предлагает Дэвид), я выхожу из всего внутреннего цикла, и BOOST_FOREACH не справляется с этим совершенно правильно для некоторых причина?

+0

Почему бы не использовать диапазон C++ 11 для цикла? –

+0

У меня есть внешние ограничения, которые ограничивают, какие версии компилятора я могу использовать, включая несколько архитектур; и, к сожалению, это означает, что я не могу использовать C++ 11; Я застрял в использовании C++ 98. –

+0

C++ 98 или C++ 03? хорошо, я пропустил версию компилятора. это C++ 03 –

ответ

4

Бьюсь об заклад, что упрощает функцию:

std::wstring const* find(std::vector<Symbol> const& sectors) { 
    if (!_sectorCodes.empty()) { 
     BOOST_FOREACH(Symbol sector, sectors) { 
      std::set<Symbol>::const_iterator it = _sectorCodes.find(sector); 
      if (it != _sectorCodes.end()) { return &*it; } 
     } 
    } 
    return NULL; 
} // find 

решает эту проблему.

Хотя с оптимизацией это трудно понять ... но по крайней мере ваш код будет более читабельным. У меня нет вашей версии gcc для тестирования, хотя у меня никогда не было проблем с моим (или clang), поэтому я могу только предложить: x

+0

Ну, этот кодовый блок находится в середине функции (т. Е. Я не просто возвращаю результат, но делаю с ним другие вещи), поэтому мне нужно добавить вспомогательную функцию для этого, но это вероятно, правильная вещь. Но основная проблема, которую я имею, заключается не в этом конкретном случае, а в том, могу ли я доверять BOOST_FOREACH, чтобы делать то, что я ожидаю. –

+1

@EdwardLoper: вы можете доверять 'BOOST_FOREACH', но можете ли вы доверять своему компилятору ... это еще один вопрос: x –

+0

Слишком верно. Но, как правило, я могу доверять тому, чтобы правильно обрабатывать и маскировать недостатки моего компилятора. :) –

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