#c #c 20 #c -coroutine
#c #c 20 #c -сопрограмма
Вопрос:
Меня смущает время жизни временных файлов, переданных в задачи сопрограммы. Рассмотрим этот пример:
cppcoro::task<> UseObject(Object constamp; object);
cppcoro::task<> CallUseObject() {
co_await UseObject(Object()); // is this valid?
}
Если бы это были функции, возвращающие void, то Object()
переданные UseObject
функции были бы уничтожены после запятой (т.е. после UseObject
завершения). Однако я не уверен, применимо ли то же самое к сопрограммам. Безопасна ли передача временного файла в подпрограмму по ссылке? Когда временные файлы уничтожаются, если это не точка с запятой?
Кроме того, в качестве проверки работоспособности всегда ли безопасно писать:
cppcoro::task<> CallUseObject() {
Object stayingalive;
co_await UseObject(stayingalive);
}
поскольку staying_alive
уничтожается после завершения co_await?
Комментарии:
1. Меня так и подмывает сказать, что
Object()
они исчезли в конце инструкции, но я могу ошибаться. Похоже, сопрограмма — отличный выбор для «передачи по значению»2. Если функция вызывает сопрограмму, которая получает параметр по ссылке, вызывающая функция отвечает за время жизни переданного объекта, пока сопрограмма не завершится. Фактически это то же правило, что и для синхронных вызовов, но теперь вам также следует иметь дело со случаем, когда функция завершена, но не завершена, и все временные файлы уничтожены. оператор co_await не помогает, потому что этот оператор работает с возвращаемым значением, которое вы получаете только после завершения функции.
3. Мой недавний опыт работы с vs2019 показывает, что ваш первый пример (Object()), деструктор не вызывается до завершения co_await.
Ответ №1:
На самом деле это является предметом открытой проблемы с текущим проектом. Цитируя проблему:
Цель состоит в том, чтобы копии / перемещения параметров (если требуется) создавались с сохранением точного типа (включая ссылки, r-ссылки и т.д.). Формулировка в 11.4.4[dcl.fct.def.coroutine] / 11, похоже, не выражает этого четко.
Исходя из этого, может показаться, что фрейм сопрограммы будет фиксировать ссылку на временное.
Поскольку co_await
это выражение, временное должно уничтожаться в конце полного выражения, в котором оно появляется. Безопасен ли ваш приведенный выше код или нет, будет зависеть от того, делает ли конкретная реализация двух задействованных сопрограмм безопасным co_await
вызов UseObject
со ссылкой на временное. В частности, обратите внимание, что то, что co_await
происходит, зависит как от типа выражения, к которому оно применяется, так и от типа обещания сопрограммы, в которой оно появляется. Кроме того, UseObject
(определение которого мы не знаем) может, по крайней мере в принципе, делать всевозможные странные вещи с указанной ссылкой…
Комментарии:
1. Я думаю, что эта половина отвечает на мой вопрос. Вы говорите, что фрейм сопрограммы должен содержать ссылку. Другая половина вопроса заключается в том, когда ссылка становится недействительной. Уничтожается ли объект до завершения co_await? Или через точку с запятой. Пожалуйста, поправьте меня, если я неправильно понял.
2. Я бы сказал, что это действительно должно произойти после точки с запятой.
co_await
это выражение. Временное значение, которое материализуется, когда prvalueObject()
привязывается к ссылке, будет уничтожено в конце полного выражения.3. ОК. Судя по вашему комментарию, этот код безопасен, потому что сопрограмма хранит ссылку на временное, которое уничтожается после уничтожения сопрограммы. Если вы объедините свой ответ и комментарий, тогда я приму ответ.
4. @sudorm-rfslash Я не думаю, что можно сказать, что это безопасно в целом. Безопасно ли это, зависит от того, что
co_await
будет сделано. Чтоco_await
происходит, зависит от типа аргумента, а также от типа обещания сопрограммы, в которой он появляется. Все, что можно сказать на основе информации, представленной в вашем вопросе, заключается в том, что вызов сопрограммы зафиксирует ссылку на временное. Безопасно ли это, зависит от конкретной реализации двух сопрограмм…5. Спасибо за обновление. Я надеюсь, что комитет упростит ответы на эти простые вопросы, прежде чем стандартизировать сопрограммы.