Clang ++ v6, 7 и 8 ошибка / неправильный результат при вычислении простой конечной разности с флагом оптимизации

Мой коллега обнаружил эту интересную / удивительную ошибку.

Он влияет на clang ++ версии 6, 7 и 8 при компиляции с флагом оптимизации (обычно -O2)

Код действительно прост, он должен вычислять конечную разницу:

a[i] = x[i+1]-x[i]
b[i] = (y[i+1]-y[i])/a[i]

Демонстрация ассоциированного кода выглядит следующим образом:

#include <iostream>
#include <vector>

class Foo {
private:
    std::vector<double> _a;
    std::vector<double> _d;

public:
    Foo(const std::vector<double> &x, const std::vector<double> &y)
        : _a(x.size()), _d(x.size()) {

        for (unsigned int i = 0; i < x.size() - 1; i++) {
            _a[i] = x[i + 1] - x[i];
            _d[i] = (y[i + 1] - y[i]) / _a[i];
        }
    }

    const std::vector<double> &a() const noexcept { return _a; }
};

int main() {

    // Read input file
    std::vector<double> x, y;
    while (std::cin) {
        double xi, yi;
        if (std::cin >> xi >> yi) {
            x.push_back(xi);
            y.push_back(yi);
        }
    }

    // Create Foo instance
    Foo foo(x, y);

    // Print computed data
    for (auto a : foo.a()) std::cout << a << '\n';

    return 0;
}

Когда вы используете неоптимизированную компиляцию clang:

$> clang++-6.0 -std=c++11 -o bug  bug.cpp
$> paste <(seq 1 5) <(seq 1 5) | ./bug

вы получите ожидаемый результат:

1
1
1
1
0

однако при оптимизации (опция -O2):

$> clang++-6.0 -std=c++11 -O2 -o bug  bug.cpp
$> paste <(seq 1 5) <(seq 1 5) | ./bug

вы получите неправильный результат:

1
2
2
0
0
  • Можете ли вы воспроизвести?
  • Это исправлено?
5
0
125
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ошибка подтверждена (с приоритетом «блокировщик выпуска») и исправлена ​​за 2 дня: подробности здесь

Пожалуйста, обрати внимание:

  • valgrind ничего не сообщает <-> трудно изолировать эту ошибку
  • g ++ не затрагивается

Я думал, что эта ошибка заслуживает упоминания, потому что она может серьезно, но незаметно, повлиять на код числовых вычислений.

Другие вопросы по теме