有状态lambda的问题-Microsoft编译器版本19.16.27024.1

时间:2018-12-20 19:14:22

标签: c++ lambda compiler-bug

嗨,我对有状态lambda表达式有疑问。

这是一个虚拟的示例,但在我看来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 ----->打印12334

clang版本8.0.0(主干) clang ++ -O3 ----->打印12334

https://godbolt.org/z/wsHYA-(代码,但没有std :: cout)

删除for循环(带有x变量的该循环)后,问题不再可见; 如果某人想知道为什么我要编写这样的代码-我想模仿协程等的行为(没什么大不了的,例如序列生成器)

1 个答案:

答案 0 :(得分:1)

这是一个优化错误,似乎与内联启动调用有关,因为未内联的lambda似乎没有问题。

这种特殊情况的解决方法是用do / while循环替换内部的for循环和goto:

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