GCC C++编译器(还有许多其他C++编译器)提供非标准扩展,例如
alloca()用于基于堆栈的allocation的一部分
从基本的角度来看,这些可以在C++20协同中使用吗?有可能吗?如果是,这是如何实施的?
据我所知,C++20协同通常在第一次调用时(即创建承诺对象时)为协同线创建堆栈框架,因此需要知道协同线堆栈帧的大小。
但是,这并不能很好地处理alloca或其他运行时动态堆栈分配。
因此,这是否可能,如果有,是如何实施的?或者这意味着什么?
发布于 2021-07-15 21:05:42
不幸的是,alloca与GCC的C++20协同不兼容。最糟糕的是编译器没有对此发出警告。
此代码示例演示了不兼容性:
#include <coroutine>
#include <iostream>
struct ReturnObject {
struct promise_type {
unsigned * value_ = nullptr;
void return_void() {}
ReturnObject get_return_object() {
return {
.h_ = std::coroutine_handle<promise_type>::from_promise(*this)
};
}
std::suspend_never initial_suspend() { return {}; }
std::suspend_never final_suspend() noexcept { return {}; }
void unhandled_exception() {}
};
std::coroutine_handle<promise_type> h_;
operator auto() const { return h_; }
};
template<typename PromiseType>
struct GetPromise {
PromiseType *p_;
bool await_ready() { return false; }
bool await_suspend(std::coroutine_handle<PromiseType> h) {
p_ = &h.promise();
return false;
}
PromiseType *await_resume() { return p_; }
};
ReturnObject counter()
{
auto pp = co_await GetPromise<ReturnObject::promise_type>{};
//unsigned a[1]; auto & i = a[0]; //this version works fine
auto & i = *new (alloca(sizeof(unsigned))) unsigned(0); //and this not
for (;; ++i) {
pp->value_ = &i;
co_await std::suspend_always{};
}
}
int main()
{
std::coroutine_handle<ReturnObject::promise_type> h = counter();
auto &promise = h.promise();
for (int i = 0; i < 5; ++i) {
std::cout << *promise.value_ << std::endl;
h();
}
h.destroy();
}https://gcc.godbolt.org/z/8zG446Esx
它应该打印0 1 2 3 4,但由于alloca的使用并不准确。
https://stackoverflow.com/questions/67576168
复制相似问题