Может ли это быть ошибкой компилятора? Моя среда это:
Я компилирую крошечную консольную программу ниже. Все хорошо работает для сборок 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;
}
Я тоже могу это воспроизвести. Когда ошибка проявляется, код тестирует 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 к другому значению чем предыдущий_пос.
Других решений пока нет …