Жахливий баг в Portland Group C++ компіляторі

Ця публікація для тих, хто змушений з обов'язку служби користуватися pgcpp компілятором або підтримувати сумісність коду з цим компілятором.

Днями я отримав баг репорт, що мій код неправильно працює, якщо його скомпілювати за допомогою pgcpp.

Почавши розбиратися, я знайшов місце, де відбувається помилка. Виявилося, що якщо код компілюється з O2 або O3 оптимізацією, то std::sort може почати дублювати частина вектора і замінювати цими дублікатами інші частини.

Ось простий C++ код, який допоможе відтворити це жахливе поведінка (зверніть увагу на кількість 3193 у виведенні):

#include < iostream>
#include < algorithm>
#include < vector>

struct ID{
ID(){};
ID(unsigned id) : Id(id){};
unsigned Id;
bool operator < ( ID const &other ) const { return Id < other.Id; } };

main(){
std::vector<ID> ids;

for (unsigned i=0; i < 5; i++)
for (unsigned id=0; id < 2000; ++id )
ids.push_back(ID(id*5+i));

std::sort(ids.begin(),ids.end());
// std::stable_sort(ids.begin(),ids.end());
for (std::vector<ID>::const_iterator it=ids.begin();it!=ids.end();++it)
std::cout << it->Id << std::endl;
}


Я тестував в Linux, але імовірно помилка відбувається і в Windows.

Написав підтримку і вони відповіли, що змогли відтворити «це поведінка», так що є надія, що баг пофиксят незабаром. Поки ж я рекомендую використовувати або std::stable_sort або (якщо є можливість вибирати) інший компілятор (у Portland Group є теж альтернативний компілятор — pgc++ — і там цей баг не спостерігається).

Всім гарного дебаггінга і поменше багів в компіляторах.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.