Проблема с сохранением состояния лямбда - Microsoft Compiler Version 19.16.27024.1 - PullRequest
0 голосов
/ 20 декабря 2018

Привет, у меня проблема с лямбда-выражением с сохранением состояния.

Это фиктивный пример, но мне кажется, что компилятор ms делает что-то не так, или, может быть, у меня какое-то неопределенное поведение?

код:

int main() {

    auto start = [x = 1, z = 1]() mutable {
        goto resume;
        for (; ; ++z) {
            for (x = 1; x < z; ++x) {
            resume:
                std::cout << z;
                if (z > 3)
                    return 1;
            }
        }
    };

    start();
}

Версия компилятора Microsoft 19.16.27024.1

cl -O2 / std: c ++ 17 (или -O1, -Ox) ----> печатает '1', а затем бесконечное число '2' (я думаю, что это неправильно)

cl -Od / std: c ++ 17 -----> печатает 12334

g ++ (Ubuntu 7.3.0-27ubuntu1 ~ 18.04) 7.3.0

g ++ -03 -----> print 12334

clang версии 8.0.0 (trunk) clang ++ -O3 ----> печатает 12334

https://godbolt.org/z/wsHYA- (код, но без std :: cout)

После удаления цикла for (этот с переменной x) проблема больше не видна;Если кто-то хочет знать, почему я написал такой код - я хочу имитировать поведение сопрограмм и т. Д. (Ничего серьезного, например, генераторы последовательностей)

1 Ответ

0 голосов
/ 20 декабря 2018

Это ошибка оптимизации, и, похоже, она связана с встраиванием вызова start, так как не встроенная лямбда не выглядит глючной.

Обходной путь для этого конкретного случая заключается в замене внутреннегодля цикла и перехода с циклом do / while:

    auto start = [x = 1, z = 1]() mutable {
        for (;; ++z) {
            do {
                std::cout << z;
                if (z > 3)
                    return 1;
            } while (++x < z);
            x = 1;
        }
    };
...