-
Notifications
You must be signed in to change notification settings - Fork 19
Description
task<> coro(any_stream& s)
{
auto [ec, n] = co_await s.read_some(buf); // may throw
// ...
}Calling and co_awaiting on a stream operation may:
- either throw, for instance upon allocator failure (not necessarily OOM: wg21.link/P1404),
- or return a non-zero
error_code, for instance upon expected EOF.
The exception path is clear: the programmer is not expecting this: their code is not prepared, so it has to be skipped: stack unwinding.
The non-zero error_code is tricky. Does it represent an error? What does _error_even mean?
The only practical or relevant meaning is "what does the function guarantee?"or in other words "what is the postcondition?" Whatever is guaranteed, the caller may take it for granted and is relieved of thinking about what happens if the guarantee is not fulfilled.
So, the question for co_await s.read_some(buf) is: do you guarantee that the buffer will be filled, or do I need to be prepared for the situation where it is not? The answer is probably "no guarantee, be prepared!" But if so, then:
- The library should document it clearly.
- It should consistently stick to this view: a non-zero
error_codeis a success, irregular but success, that is, no precondition failure. In that casewhen_all/when_anyshould also recognize a non-zeroerror_codeas success: the caller of the algorithm will determine what to do with the irregular successes.
When doing (for whatever reason):
co_await when_any(
stream1.read_some(buf1),
stream2.read_some(buf2),
); You should get the first that returns even with a non-zero ec; even if the other one would have returned with a zero ec. Because this is the contract of stream1.read_some(buf1): getting a non-zero ec is success.