Возможная ошибка компилятора VS2012 (возможно, в Оптимизации всей программы?)

Может ли это быть ошибкой компилятора? Моя среда это:

  • Win7 pro (64-разрядная версия)
  • VS2012 (обновление 3)

Я компилирую крошечную консольную программу ниже. Все хорошо работает для сборок x64 bit release / debug. Отладочная сборка x32 также отлично работает. Тем не менее, сборка выпуска x32 отображает сообщение «BUG!».

Если я отключу «Оптимизацию всей программы», это решит проблему.

Есть идеи?

#include <string>
#include <iostream>int main()
{
std::string const buffer = "hello, world";
std::string::size_type pos = 0;
std::string::size_type previous_pos;while (pos != std::string::npos)
{
previous_pos = ++pos;
pos = buffer.find('w', pos);
}if (previous_pos == std::string::npos)
{
std::cout << "BUG!!"<< std::endl;
}

return 0;
}

4

Решение

Я тоже могу это воспроизвести. Когда ошибка проявляется, код тестирует eax, чтобы определить, выводить ли «BUG», который является тем же регистром, который используется для «pos».

17:         previous_pos = ++pos;

013C12E5 inc eax

21:     if (previous_pos == std::string::npos)

00301345 cmp eax, eax
00301347 jne main + 0F6h (0301366h)

Однако, если вы сделаете изменение, чтобы попытаться заставить оптимизатор понять, что они различны, тогда тест будет другим. Если я добавлю ++ previous_pos в конец тела цикла, то он использует ecx для previous_pos, и ошибка исчезнет:

22:     if (previous_pos == std::string::npos)

00361349 cmp ecx, eax
0036134B jne main + 0FAh (036136Ah)

Если я изменю поиск на pos = buffer.find (‘w’, previous_pos); ‘ (поиск по предыдущей_позиции вместо pos, который имеет то же значение), затем он использует ebx, и снова ошибка исчезает:

21:     if (previous_pos == std::string::npos)

00191345 cmp ebx, eax
00191347 jne main + 0F6h (0191366h)

Поэтому в оригинале кажется, что оптимизатор ошибочно решает, что он может использовать eax для обеих этих переменных, несмотря на строку ‘pos = buffer.find (‘ w ‘, pos);’ это может установить pos к другому значению чем предыдущий_пос.

4

Другие решения

Других решений пока нет …