std::lifetime
В С++ возникла проблема отслеживания лайфтаймов и особенно сильно она проявляется в корутинах, где недостаточно умный компилятор не может оптимизировать аллокацию. Моя идея поможет с этими проблемами и вроде довольно изящно. Суть: Представим, что корутина по ссылке захватила в себя объект из скоупа, где создана, а в конце корутины обращается по этой ссылке и вызывает скажем метод. Если эта ссылка висячая, то это уб, значит этого не может быть, а значит корутина гарантированно переживает переменную по ссылке(если это валидный код). А значит можно не аллоцировать память для этой корутины и сделать её на стеке. Грубо говоря:
// корутина
task Foo(lifetime_t& life) {
scope_exit { life.end() };
/// ...
co_return;
}
void Bar () {
lifetime_t life;
Foo(life);
}
Теперь можно добавить к этому немного поддержки стандартной библиотеки
consteval auto std::current_scope() noexcept -> std::lifetime_t;
struct life {
[[no_unique_address]] std::lifetime_t& lifetime; // некая компиляторная магия позволяющая ссылке тут быть пустой
~life() {
std::die(lifetime);
}
};
std::current_scope действует по аналогии с std::current_location() только на компиляции. Возвращает уникальное значение типа std:::lifetime_t, которое умеет сравниваться(чтобы быть использованным в качестве шаблонного параметра) Тогда представим реализацию функции-корутины, возвращающей std::generator, который точно знает что всегда может быть на стеке И специальный std::life, который является пустой обёрткой(не занимающей памяти) над std::lifetime_t, которая в деструкторе обращается по ссылке к объекту типа std::lifetime_t
std::generator<int> Foo(std::life = std::current_scope()) {
co_yield 5;
// в конце вызывается деструктор life, а если корутина
// пережила скоуп, то это уб(обращение по невалидной ссылке), а значит аллоцировать не нужно
co_return;
}
Хак прикольный, но не даёт 100% гарантии - компилятор может недостаточно хорошо заинлайнить, или тело корутины может оказаться слишком большим, или сама корутина окажется многомегабайтной, или режим оптимизации недостаточно выкручен...
Хак прикольный, но не даёт 100% гарантии - компилятор может недостаточно хорошо заинлайнить, или тело корутины может оказаться слишком большим, или сама корутина окажется многомегабайтной, или режим оптимизации недостаточно выкручен...
ну если добавлять это в стандарт, то гарантировать оптимизацию по типу возврата из функции
Хак прикольный
https://github.com/cpp-ru/ideas/issues/514 А вот это не прикольно?()