Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problem with stateful lambda - Microsoft Compiler Version 19.16.27024.1

Hi I have problem with stateful lambda expression.

This is dummy example, but it seems to me that ms compiler is doing something wrong, or maybe I have some undefined behavior?

code:

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 Compiler Version 19.16.27024.1

cl -O2 /std:c++17 (or -O1, -Ox) -----> prints '1' and then infinite number of '2' (wrong I think)

cl -Od /std:c++17 -----> prints 12334

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

g++ -03 -----> prints 12334

clang version 8.0.0 (trunk) clang++ -O3 -----> prints 12334

https://godbolt.org/z/wsHYA- (code but without std::cout)

After removing for loop (this one with x variable) problem is no longer visible; If somone want to know why I wrote code like this - I want to imitate the behavior of coroutines etc. (nothing serious, for example sequences generators)

like image 949
Krzysztof Sommerfeld Avatar asked Dec 20 '18 19:12

Krzysztof Sommerfeld


1 Answers

It's an optimization bug, and seems to be related to inlining the call to start, as the non-inlined lambda does not appear to be buggy.

A workaround for this particular case is to replace the inner for loop and goto with a do/while loop:

    auto start = [x = 1, z = 1]() mutable {
        for (;; ++z) {
            do {
                std::cout << z;
                if (z > 3)
                    return 1;
            } while (++x < z);
            x = 1;
        }
    };
like image 51
1201ProgramAlarm Avatar answered Oct 14 '22 23:10

1201ProgramAlarm