You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

协程co_await操作中,操作对象类型是否必须具备复制或移动构造能力?MSVC与GCC编译差异分析

Which Compiler's Behavior Conforms to the C++ Standard for This Coroutine co_await Scenario?

Let's walk through this problem step by step, tying each compiler's behavior back to the C++20 coroutine standard.

First, recap the scenario: we have a task coroutine return type with deleted copy and move constructors. We create a suspended coroutine f, then define another coroutine g that runs co_await f. MSVC compiles this code without issues, but GCC 11.2 throws an error about a missing move constructor, and GCC trunk complains about a missing copy constructor.

What the C++ Standard Says About co_await

To resolve this, we need to reference the rules for co_await expressions (defined in the [expr.await] section of the C++20 standard):

  1. Evaluating the operand: When we write co_await f, f is a left-value reference to our task object. The standard does not require copying or moving the operand here—we can work directly with the reference.
  2. Obtaining the awaiter: Our task class already implements the three required awaiter methods (await_ready, await_suspend, await_resume), so the task object itself acts as the awaiter. There's no need to create a new task instance; we can use the existing f via its reference.
  3. Lifetime safety: Since f is declared in main and we resume g within main, f's lifetime covers the entire co_await operation. The standard does not force implementations to copy the awaitable object when a valid, long-lived reference is available.

Analyzing Compiler Behavior

  • MSVC: It correctly uses the reference to f throughout the co_await process, never attempting to copy or move the task instance. This matches the standard's requirements perfectly—there's no rule mandating duplication of the awaitable object when a reference works.
  • GCC: Both versions of GCC incorrectly try to copy or move f during co_await processing. This isn't required by the standard, and the inconsistency between versions (requesting move vs copy constructors) points to an implementation bug in how GCC handles reference operands for co_await.

Conclusion

MSVC's behavior aligns with the C++ standard, while GCC's behavior here is incorrect due to an unnecessary attempt to copy or move the awaitable object.

内容的提问来源于stack exchange,提问作者Fedor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 08:59:07