Cette question découle de ce commentaire: explication de la durée de vie Lambda pour les coroutines C ++ 20
concernant cet exemple:
auto foo() -> folly::coro::Task<int> {
auto task = []() -> folly::coro::Task<int> {
co_return 1;
}();
return task;
}
La question est donc de savoir si l'exécution de la coroutine renvoyée par foo
entraînerait UB.
"Appeler" une fonction membre (après la fin de la durée de vie de l'objet) est UB: http://eel.is/c++draft/basic.life#6.2
... tout pointeur qui représente l'adresse de l'emplacement de stockage où l'objet sera ou était situé peut être utilisé, mais uniquement de manière limitée. [...] Le programme a un comportement indéfini si:
[...]
- le pointeur est utilisé pour accéder à un membre de données non statique ou appeler une fonction membre non statique de l'objet , ou
Cependant, dans cet exemple:
- l'
()
opérateur du lambda est appelé alors que la durée de vie du lambda est toujours valide - Il est alors suspendu,
- alors la lambda est détruite,
- puis la fonction membre (opérateur
()
) est reprise à un moment donné par la suite.
Cette reprise est-elle considérée comme un comportement indéfini?
la source
this
pointeur est invalidée. Considérez également la discussion dans les commentaires.Réponses:
[dcl.fct.def.coroutine] p3 :
Le paramètre d'objet implicite est dans votre exemple une référence const, et donc cette référence sera suspendue lorsque l'exécution reprendra après que l'objet de fermeture a été détruit.
Cependant, sur la note des objets détruits lors de l'exécution d'une fonction membre, c'est bien en soi, et rien d'autre que la norme elle-même n'implique cela dans [de base] :
(NB: l'UB ci-dessus est parce que l'implicite
this
n'est pas blanchi et fait toujours référence au paramètre d'objet implicite.)Votre exemple semble donc bien défini, conditionnel à l'idée que la reprise de l'exécution ne relève pas des mêmes règles qu'une invocation d'origine. Notez que la référence à l'objet de fermeture peut être suspendue, mais il n'y a aucun accès entre la suspension et la reprise.
la source