C++ coroutine's return_void's and return_value's return type

return_void

consider the coroutine's ReturnObject below and note the comments before the method ReturnObject::promise_type::return_void :

struct ReturnObject {
        struct promise_type {
            int val_{23};
            ReturnObject get_return_object() {
                return {std::coroutine_handle<promise_type>::from_promise(*this)}; 
            }
        std::suspend_never initial_suspend() { return {}; }
        std::suspend_never final_suspend() noexcept { return {}; }
        void unhandled_exception() {}

         /*** NOTE THIS ***/
        //void return_void(){  }
        
        /*** AND THIS ***/
        int return_void(){ return 101; }
      };
      
      std::coroutine_handle<promise_type> h_; 
      ReturnObject(std::coroutine_handle<promise_type> h):h_{h}{ } 
      operator std::coroutine_handle<promise_type>() const { return h_; } 
};

Full code on compiler explorer

The standard usage on the web and in this paper (page 37) suggests that the return_void method returns void but in gcc 11.2, the return_void with int return type works as well. Is this correct ? If yes,

  1. why does it work with both void and non-void return type ?
  2. what happens to the return value of the return_void in the case of non-void return type?

return_value

Similar effects with the method return_value can be observed in gcc. In case of the return_value's returned data, is there a way to access this returned data directly, similar to the normal subroutine/function's returned value ?

Check the code on compiler explorer

Update:

After @useless's suggestion, I added [[nodiscard]] to both return_void and return_value with non-void return types and enabled -Wall flag.

Surprisingly for return_void and return_value I don't even get a warning with gcc-10.2. Check here but gcc-11.2 gives me a warning (here)

The compiler warning I get for return_value with int return type looks like below

warning: ignoring return value of 'int ReturnObject::promise_type::return_value(int)', declared with attribute 'nodiscard' [-Wunused-result]
   31 |     co_return 7;
      |               ^
<source>:18:27: note: declared here
   18 |         [[nodiscard]] int return_value(int val){return val;}

I'm not convinced from the compiler warning that co_returns value is being discarded. In reality the return value being discarded is from the method return_value but the compiler manages to shroud it some how.

Thanks for looking at the post and for suggestions in advance.


Solution 1:

[stmt.return.coroutine]/2 says that the expressions

promise_object.return_value(...)

and

promise_object.return_void()

(whichever is used by the co_return) shall be of type void.

So the return type of either function must be void (if it is used by a co_return).

MSVC does correctly reject the program:

<source>(31): error C7625: The type of a coroutine promise return_value or return_void expression must be void
<source>(18): note: see declaration of 'ReturnObject::promise_type::return_value'