Три строчки, которые считали неправильно: баг в компиляторе
Мы написали программу на C++, и она работала неправильно. Не падала, не зависала — просто выдавала математически неверный результат.
Я позвал коллег, и мы стали разбираться. Проверили всё построчно — каждая строчка правильная, а результат всё равно неправильный.
Тогда начали упрощать. Убрали класс — неправильно. Убрали лишние файлы — неправильно. Выкидывали всё, что не нужно, и каждый раз результат оставался неверным. В итоге программа сократилась буквально до трёх-четырёх строк. И даже они считали неправильно.
Дальше в исходнике смотреть было уже нечего, поэтому мы её дизассемблировали и посмотрели на ассемблер. И увидели: компилятор именно в этом месте перепутал регистры — записывал значение в один регистр, а читал из другого. Ошибка была не в нашем коде, а в Microsoft Visual C++.
Мы отправили баг-репорт в Microsoft.
Что я из этого вынес: когда всё проверено и всё равно не сходится, урезай программу до минимального примера, который ещё ломается. Обычно на этом пути находится своя ошибка. Но если от программы остались три строчки, а она всё ещё врёт, пора смотреть ниже — в ассемблер. И только тогда можно поверить, что виноват компилятор.