To pytanie wynika z tego komentarza: Lambda dożywotniego wyjaśnienia dla korupcji w C ++ 20
w odniesieniu do tego przykładu:
auto foo() -> folly::coro::Task<int> {
auto task = []() -> folly::coro::Task<int> {
co_return 1;
}();
return task;
}
Pytanie brzmi więc, czy wykonanie zwróconej przez niego coroutine foo
spowoduje UB.
„Wywołanie” funkcji członka (po zakończeniu życia obiektu) to UB: http://eel.is/c++draft/basic.life#6.2
... każdy wskaźnik reprezentujący adres miejsca przechowywania, w którym obiekt będzie lub był zlokalizowany, może być używany, ale tylko w ograniczonym zakresie. [...] Program ma niezdefiniowane zachowanie, jeśli:
[...]
- wskaźnik jest używany do uzyskania dostępu do elementu danych niestatycznych lub wywołania funkcji elementu niestatycznego obiektu , lub
Jednak w tym przykładzie:
()
operator lambda nazywa się natomiast żywotność lambda jest nadal ważny- Następnie jest zawieszony,
- wtedy lambda zostaje zniszczona,
- a następnie funkcja członka (operator
()
) zostanie wznowiona w pewnym momencie później.
Czy to wznowienie jest uważane za niezdefiniowane zachowanie?
źródło
this
wskaźnik jest unieważniany. Rozważ także dyskusję w komentarzach.Odpowiedzi:
[dcl.fct.def.coroutine] p3 :
Niejawny parametr obiektu jest w twoim przykładzie stałym odwołaniem, a zatem odniesienie to będzie wisieć, gdy wykonanie zostanie wznowione po zniszczeniu obiektu zamknięcia.
Jednak z uwagi na to, że obiekty są niszczone podczas wykonywania funkcji składowej, jest to w gruncie rzeczy w porządku i nic innego, jak sam standard implikuje to w [podstawowym] :
(Uwaga: powyższy UB wynika z tego, że niejawne
this
nie jest prane i nadal odnosi się do parametru niejawnego obiektu).Twój przykład wydaje się być dobrze zdefiniowany, pod warunkiem, że wznowienie wykonania nie będzie podlegać tym samym regułom, co oryginalne wywołanie. Zauważ, że odwołanie do obiektu zamknięcia może być wiszące, ale nie jest dostępne w żaden sposób między zawieszeniem a wznowieniem.
źródło