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

标签 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();
}

微软编译器版本 19.16.27024.1

cl -O2/std:c++17 (or -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 变量)后问题不再可见; 如果有人想知道为什么我写这样的代码 - 我想模仿协程等的行为(没什么大不了的,例如序列生成器)

最佳答案

这是一个优化错误,似乎与内联启动调用有关,因为非内联 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;
        }
    };

关于c++ - 有状态 lambda 问题 - Microsoft 编译器版本 19.16.27024.1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53874716/

相关文章:

filter - Java - Lambda 过滤条件,忽略添加到 map

objective-c - 将 NSError ** 作为方法参数传递时出现编译器警告

c++ - MSVC : Invalid memcpy optimization?

Scala 隐式转换在某些条件下应用,但在其他条件下不应用

c++ - 为什么 std::async 不能与接收抽象类引用作为参数的函数一起使用?

java - Java lambda 可以有超过 1 个参数吗?

lambda - Kotlin Any 和 lambda

c++ - 我可以将参数传递给 SIGINT 吗?

C++:模板成员函数,如 template<typename T> int foo<T>()

c++ - 在类中使用具有非静态大小的数组