Boost logo

Boost :

Subject: Re: [boost] [system] Would it be possible to trial a breaking change to Boost.System and see what happens?
From: Christopher Kohlhoff (chris_at_[hidden])
Date: 2018-01-15 13:27:44


Hi Peter,

> On 15 Jan 2018, at 12:47 am, Peter Dimov via Boost <boost_at_[hidden]> wrote:
>
> Christopher Kohlhoff wrote:
>
>> > There must exist a generic way to test for failure.
>>
>> Why must this exist? (With the emphasis placed on "generic".)
>
> For the reason I stated; so that one can write a function whose logic is not broken when a callee switches (or is switched, or is ported) to another implementation and starts returning error codes from a different domain.

This is not logical. Part of being able to switch backends is that both backends adhere to a given specification. In the error handling model in your example, this specification would stipulate that on failure a function produces a non-zero-valued error code. Producing the errors from a different domain doesn't change that fact. However, this property is independent of the error_code itself; it is a property of your specification.

> And similarly, so that one can use several helper functions in one's implementation, each returning codes from a different domain, without the caller being hopelessly confused by it. That's what "encapsulate" means - to achieve a degree of independence.

Your example also follows an error handling model where, following a given function call, you test the error code before anything else to determine success or failure. My view is that the error_code class should be (and is) usable wherever one currently uses platform errors such as errno or GetLastError. The system calls that use these platform errors, by and large, require you to test the result first to determine success or failure and in some cases return an error code on success. The widespread use of this approach is why I assert that the requirement is not "generic". I don't intend to pass judgement here on the design merits of one approach or the other, but simply note that both exist and each have their pros and cons.

> Having a generic way does not in any way preclude one to be able to (re)interpret success/failure in the concrete case, when the errors returned are of a specific fixed domain. That's a separate use case and it won't go away.
>
> A generic success condition is conceptually not any different from a generic "not found" condition. If you have domain-specific knowledge about what is a success, you won't compare to generic success, and if you have domain-specific knowledge about what wasn't found, you won't compare to generic not found. And consequently, an argument against the former is also an argument against the latter.

Originally you phrased it as a generic way to test for failure, but I think I mostly agree with you if you instead phrase it in terms of success (as you are now doing). Specifically, in a test-the-error-first approach, you can consider a zero-valued error_code as an *unqualified* success, and all error categories must adhere to this to enable this approach. This satisfies the requirements of your example and does not preclude the existence of other error codes that represent *qualified* success and require additional contextual information to assess.

This is essentially existing practice, so I think I could support codifying this much in the standard if you think it worthwhile. (The current plan was just to present it as a best practice in a paper I am writing.)

Cheers,
Chris


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk