У меня есть следующий фрагмент кода, однако при компиляции его с GCC 4.4 с различными флагами оптимизации я получаю некоторые неожиданные результаты при его запуске.
#include <iostream>
int main()
{
const unsigned int cnt = 10;
double lst[cnt] = { 0.0 };
const double v[4] = { 131.313, 737.373, 979.797, 731.137 };
for(unsigned int i = 0; i < cnt; ++i) {
lst[i] = v[i % 4] * i;
}
for(unsigned int i = 0; i < cnt; ++i) {
double d = v[i % 4] * i;
if(lst[i] != d) {
std::cout << "error @ : " << i << std::endl;
return 1;
}
}
return 0;
}
при компиляции с: "g ++ -pedantic -Wall -Werror -O1 -o test test.cpp" Я получаю следующий вывод: "error @: 3 «
при компиляции с: "g ++ -pedantic -Wall -Werror -O2 -o test test.cpp" Я получаю следующий вывод: "error @: 3 «
при компиляции с: "g ++ -pedantic -Wall -Werror -O3 -o test test.cpp" Я не получаю ошибок
при компиляции с: "g ++ -pedantic -Wall -Werror -o test test.cpp" Я не получаю ошибок
Я не считаю, что это проблема, связанная с округлением или эпсилон-разницей в сравнении. Я пробовал это с Intel v10 и MSVC 9.0, и все они, кажется, работают как ожидалось. Я считаю, что это должно быть не более чем побитовое сравнение.
Если я заменю оператор if следующим: if (static_cast<long long int>(lst[i]) != static_cast<long long int>(d))
и добавлю "-Wno-long-long", я не получу ошибок ни в одном из режимов оптимизации при запуске.
Если я добавлю std::cout << d << std::endl;
до «return 1», я не получу ошибок ни в одном из режимов оптимизации при запуске.
Это ошибка в моем коде, или что-то не так с GCC и тем, как он обрабатывает тип double?
Примечание: Я только что попробовал это с gcc версий 4.3 и 3.3, ошибка не отображается.
Разрешение: Майк Динсдейл отметил следующее сообщение об ошибке: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=323 Кажется, что команда GCC не не совсем уверена в природе проблемы.
Как предлагается в отчете об ошибках, возможное решение - использовать опцию ffloat-store. Я попробовал это, и это работает, однако результаты с точки зрения производительности не так уж хороши, хотя ymmv.