嗨,我对有状态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变量的该循环)后,问题不再可见; 如果某人想知道为什么我要编写这样的代码-我想模仿协程等的行为(没什么大不了的,例如序列生成器)
答案 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;
}
};