Этот вопрос вытекает из этого комментария: объяснение времени жизни лямбда для сопрограмм C ++ 20
относительно этого примера:
auto foo() -> folly::coro::Task<int> {
auto task = []() -> folly::coro::Task<int> {
co_return 1;
}();
return task;
}
Таким образом, вопрос заключается в том, foo
приведет ли выполнение возвращаемой сопрограммы к UB.
«Вызов» функции-члена (после окончания времени жизни объекта) - UB: http://eel.is/c++draft/basic.life#6.2
... любой указатель, который представляет адрес места хранения, где объект будет или был расположен, может использоваться, но только ограниченным образом. [...] Программа имеет неопределенное поведение, если:
[...]
- указатель используется для доступа к нестатическому члену данных или для вызова нестатической функции-члена объекта , или
Однако в этом примере:
()
оператор лямбда называется в то время как срок службы лямбда остается в силе- Затем приостановлено,
- тогда лямбда уничтожается,
- и затем функция-член (оператор
()
) возобновляется в некоторый момент позже.
Считается ли это возобновление неопределенным поведением?
c++
language-lawyer
c++20
c++-coroutine
Майк Луи
источник
источник
this
указатель становится недействительным. Учтите также обсуждение в комментариях.Ответы:
[dcl.fct.def.coroutine] p3 :
Параметр неявного объекта в вашем примере является константной ссылкой, и, следовательно, эта ссылка будет зависать при возобновлении выполнения после уничтожения объекта закрытия.
Однако, на заметку об объектах, уничтожаемых во время выполнения функции-члена, это действительно хорошо само по себе, и никто, кроме самого стандарта, не подразумевает этого в [basic] :
(NB: UB выше, потому что неявное
this
не стирается и все еще ссылается на неявный параметр объекта.)Таким образом, ваш пример выглядит четко определенным, при условии, что возобновление выполнения не подпадает под те же правила, что и исходный вызов. Обратите внимание, что ссылка на объект замыкания может быть висящей, но между приостановкой и возобновлением к ней нет доступа.
источник