Я уверен, что есть ошибка в оптимизаторе в Visual Studio 2005. Проблема с картой STL.
Вот соответствующий код:
MyMapIterator myIt = m_myMap.find(otherID);
if (myIt != m_myMap.end() && myIt->second.userStatus == STATUS_A)
{
//Prints stuff. No side-effects whatsoever.
}
else if (myIt != m_myMap.end() && myIt->second.userStatus == STATUS_B && myIt->second.foo == FOO_A)
{
//Prints stuff. No side-effects whatsoever.
}
else if (myIt != m_myMap.end() && myIt->second.userStatus == STATUS_B && myIt->second.foo == FOO_B && /*other meaningless conditions */)
{
//Prints stuff. No side-effects whatsoever.
}
Работает безупречно при отладке, используется для сбоя при выпуске и отключения глобальных оптимизаций "исправил это" Теперь ничего не работает. Я получаю:
Microsoft Visual Studio C Runtime Library has detected a fatal error in [...]
Press Break to debug the program or Continue to terminate the program.
Это происходит на первом MyMapIterator :: operator-> последнего, если
Карта пуста, я знаю, что find должен был вернуть end (), первые два сравнения с этим эффектом работают. Но каким-то образом третий раз myIt! = M_myMap.end () возвращает значение true, и выполняется правая часть &&.
В некоторых других местах происходит сбой, как в случае с вариантом 'myIt! = M_myMap.end ()', возвращающим true в том же файле, но для меня это тот, который исключает большинство других возможностей. Раньше я думал, что это переполнение буфера, которое топает мою карту, но оглянемся на код. Я уверен, что никакой другой поток не топает это, и это на 100% воспроизводимо.
Итак, что мне делать отсюда. Это не чувствительно к производительности в малейшей степени. Мне просто нужно, чтобы он работал как надо. Любой вариант приемлем. Да, я знаю, что мог бы окружить все это проверкой равенства итераторов, и это не самый хороший код. Дело в том, что он все еще должен работать, и если это не сработает, все остальное может.
EDIT
Последний оператор if-if не генерирует скачок!
if (myIt != m_myMap.end() && myIt->second.userStatus == STATUS_A)
009270BE mov ecx,dword ptr [this]
009270C4 add ecx,0Ch
009270C7 lea eax,[ebp-90h]
009270CD call std::_Tree<std::_Tmap_traits<unsigned __int64,lux::Foo,std::less<unsigned __int64>,std::allocator<std::pair<unsigned __int64 const ,lux::Foo> >,0> >::end (8A21E0h)
009270D2 mov esi,eax
009270D4 lea edi,[myIt]
009270D7 call std::_Tree<std::_Tmap_traits<unsigned __int64,lux::Foo,std::less<unsigned __int64>,std::allocator<std::pair<unsigned __int64 const ,lux::Foo> >,0> >::const_iterator::operator!= (8A2220h)
009270DC movzx ecx,al
009270DF test ecx,ecx
009270E1 je lux::Bar::DoStuff+0E4h (927154h)
009270E3 lea esi,[myIt]
009270E6 call std::_Tree<std::_Tmap_traits<unsigned __int64,lux::Foo,std::less<unsigned __int64>,std::allocator<std::pair<unsigned __int64 const ,lux::Foo> >,0> >::iterator::operator-> (8A21F0h)
009270EB cmp dword ptr [eax+8],1
009270EF jne lux::Bar::DoStuff+0E4h (927154h)
{
Stuff
}
else if (myIt != m_myMap.end() && myIt->second.userStatus == STATUS_B)
00927154 mov ecx,dword ptr [this]
0092715A add ecx,0Ch
0092715D lea eax,[ebp-98h]
00927163 call std::_Tree<std::_Tmap_traits<unsigned __int64,lux::Foo,std::less<unsigned __int64>,std::allocator<std::pair<unsigned __int64 const ,lux::Foo> >,0> >::end (8A21E0h)
00927168 mov esi,eax
0092716A lea edi,[myIt]
0092716D call std::_Tree<std::_Tmap_traits<unsigned __int64,lux::Foo,std::less<unsigned __int64>,std::allocator<std::pair<unsigned __int64 const ,lux::Foo> >,0> >::const_iterator::operator!= (8A2220h)
00927172 movzx edx,al
00927175 test edx,edx
00927177 je lux::Bar::DoStuff+17Ah (9271EAh)
00927179 lea esi,[myIt]
0092717C call std::_Tree<std::_Tmap_traits<unsigned __int64,lux::Foo,std::less<unsigned __int64>,std::allocator<std::pair<unsigned __int64 const ,lux::Foo> >,0> >::iterator::operator-> (8A21F0h)
00927181 cmp dword ptr [eax+8],2
00927185 jne lux::Bar::DoStuff+17Ah (9271EAh)
{
//Stuff
}
else if (myIt != m_myMap.end() && myIt->second.userStatus == STATUS_C)
009271EA mov ecx,dword ptr [this]
009271F0 add ecx,0Ch
009271F3 lea eax,[ebp-0A0h]
009271F9 call std::_Tree<std::_Tmap_traits<unsigned __int64,lux::Foo,std::less<unsigned __int64>,std::allocator<std::pair<unsigned __int64 const ,lux::Foo> >,0> >::end (8A21E0h)
009271FE mov esi,eax
00927200 lea edi,[myIt]
00927203 call std::_Tree<std::_Tmap_traits<unsigned __int64,lux::Foo,std::less<unsigned __int64>,std::allocator<std::pair<unsigned __int64 const ,lux::Foo> >,0> >::const_iterator::operator!= (8A2220h)
00927208 lea esi,[myIt]
0092720B call std::_Tree<std::_Tmap_traits<unsigned __int64,lux::Foo,std::less<unsigned __int64>,std::allocator<std::pair<unsigned __int64 const ,lux::Foo> >,0> >::iterator::operator-> (8A21F0h)
{
//Stuff in the condition and after