Hi Peter,
On 14 Jan 2018, at 4:02 pm, Peter Dimov via Boost
wrote: Christopher Kohlhoff wrote:
Instead, the correspondence of particular error_code values to success or failure is context specific and is defined by an API.
I don't agree. In the general case,
void f( error_code& ec ) { ec.clear();
do_f1( ec ); if( !ec ) return;
do_f2( ec ); if( !ec ) return;
do_f3( ec ); if( !ec ) return; }
`f` should not need to know what errors are being returned by `do_f1`, `do_f2`, `do_f3`, in order to check whether the calls succeeded; the whole point of using error_code is that errors from different domains can be handled in a generic manner.
No, this is just one approach to error handling, and defining the error handling approach is beyond error_code's scope. The responsibility of error_code is simply to encapsulate the error values that originate from different domains.
This is similar to exceptions;
On the contrary, one important reason for using error_code (I won't say the whole point, because it isn't) is that it enables error handling that is fundamentally different to exceptions. With exceptions, the notion of success or failure is determined by the callee. With error_codes, we also allow success or failure to be determined by the caller. This is existing practice not just with error_code but with the error code systems that it wraps. For example: HANDLE h = CreateMutex(0, TRUE, name); if (h == NULL) // Failure. else if (GetLastError() == ERROR_ALREADY_EXISTS) // Success or failure depends on the context. else // Success. (Or is it? Maybe detecting the existing mutex is what was desired.)
There must exist a generic way to test for failure.
Why must this exist? (With the emphasis placed on "generic".) You can achieve this within certain domains and error handling designs, sure. However, testing for failure using only the error code is not possible for all use cases where error codes are applicable or, indeed, already used. Cheers, Chris