在以下情况下,我发现了一些非常奇怪的行为(在 clang 和 GCC 上)。我有一个向量,nodes一个元素,一个 class 的实例Node。然后我调用一个函数nodes[0],Node为向量添加一个新的。添加新节点时,调用对象的字段将重置!然而,一旦功能完成,它们似乎又恢复正常。
我相信这是一个最小的可重复示例:
#include <iostream>
#include <vector>
using namespace std;
struct Node;
vector<Node> nodes;
struct Node{
int X;
void set(){
X = 3;
cout << "Before, X = " << X << endl;
nodes.push_back(Node());
cout << "After, X = " << X << endl;
}
};
int main() {
nodes = vector<Node>();
nodes.push_back(Node());
nodes[0].set();
cout << "Finally, X = " << nodes[0].X << endl;
}
Run Code Online (Sandbox Code Playgroud)
哪些输出
#include …Run Code Online (Sandbox Code Playgroud) Folly为 C++20 风格的协程提供了一个可用的库。
在自述文件中,它声称:
重要提示:您需要非常小心临时 lambda 对象的生命周期。调用 lambda 协程会返回一个 folly::coro::Task 捕获对 lambda 的引用,因此如果返回的 Task 没有立即 co_awaited 那么当临时 lambda 超出范围时,任务将留下悬空引用。
我尝试为他们提供的示例制作 MCVE,但对结果感到困惑。为以下所有示例假设以下样板:
#include <folly/experimental/coro/Task.h>
#include <folly/experimental/coro/BlockingWait.h>
#include <folly/futures/Future.h>
using namespace folly;
using namespace folly::coro;
int main() {
fmt::print("Result: {}\n", blockingWait(foo()));
}
Run Code Online (Sandbox Code Playgroud)
我用地址消毒剂编译了以下内容,以查看是否有任何悬空引用。
编辑:澄清的问题
根据cppreference:
当协程到达 co_return 语句时,它执行以下操作:
...
- 或为 co_return expr 调用 promise.return_value(expr),其中 expr 具有非 void 类型
- 以与创建它们相反的顺序销毁所有具有自动存储持续时间的变量。
- 调用 promise.final_suspend() 和 co_await 的结果。
因此,也许临时 lambda 的状态在返回结果之前实际上不会被破坏,因为foo它本身是一个协程?
ASAN 错误:我假设在等待协程时“i”不存在
auto foo() -> …Run Code Online (Sandbox Code Playgroud)