🍺
Coroutine и scope: как co_await разрывает привычную модель блочной видимостиКорутины в C++20 нарушают базовую интуицию о scope: локальные переменные могут пережить
} функции. Разбираем, как это реализовано.
🍪
Проблема стекаОбычная функция: локальные переменные в стеке, уничтожаются при
return. Корутина может быть приостановлена (
co_await) и возобновлена позже — стека уже нет. Куда деваются локальные переменные?
Task example() {
int x = 10; // где живёт x после co_await?
co_await someAwaitable();
std::cout << x; // x должен быть доступен!
}⚡️
Coroutine frame в heapКомпилятор переписывает корутину в конечный автомат. Все локальные переменные, которые живут через точку приостановки, переносятся в
coroutine frame — объект в куче:
// Псевдокод того, что генерирует компилятор:
struct __example_frame {
int x; // из стека → в heap
int __state; // текущая точка возобновления
promise_type __promise;
};
‼️
Scope остаётся лексическимВидимость имён не меняется —
x виден только внутри функции. Меняется место хранения: не стек, а heap. Деструкторы по-прежнему вызываются при выходе из scope — но «выход» теперь может произойти через
co_return или уничтожение корутины.
💡 Корутины не нарушают лексическую область видимости — они нарушают связь между scope и стеком. Локальные переменные остаются «локальными» по видимости, но физически мигрируют в heap.
📍
Навигация: Вакансии • Задачи • СобесыБиблиотека C/C++ разработчика #константная_правильность