Subject: Re: [boost] Reforming Boost.System and <system_error> round 2
From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2018-01-17 00:01:15
On Wed, Jan 17, 2018 at 2:44 AM, Andrzej Krzemienski <akrzemi1_at_[hidden]> wrote:
> 2018-01-17 0:29 GMT+01:00 Andrey Semashev <andrey.semashev_at_[hidden]>:
>> On Wed, Jan 17, 2018 at 1:16 AM, Andrzej Krzemienski via Boost
>> <boost_at_[hidden]> wrote:
>> > 2018-01-16 19:58 GMT+01:00 Andrey Semashev via Boost
>> > <boost_at_[hidden]>
>> > :
>> >> There's nothing ambuguous about the conversion operator, as it is
>> >> specified in the standard, and I find the syntax quite intuitive.
>> > You say you find the syntax quite intuitive. But do you also find the
>> > semantics intuitive? When you type or read `if(ec)` do you interpret it
>> > as
>> > "if operation failed" or as "if operation returned code of numeric value
>> > zero, regardless of the domain and regardless of whether in this domain
>> > zero means success or failure"?
>> The two interpretations are equivalent for me, because in my code
>> error code of zero always means "success". Why? Because I pick the
>> error values that way (or map them that way, if the values come from
>> an external API) so that they play nicely with `error_code` design and
>> the rest of the code.
>> If we support multiple "success" values or non-zero success values, I
>> would expect "if (err)" to mean "if some error happened". Why? Because
>> that "if" controls error handling, not an arbitrary non-zero result
>> handling. I've never seen or written code that does otherwise.
>> If I want to test for a particular error code, I would write "if (err
>> == x)" or "if (err != x)" - that's the syntax that communicates the
>> intent to check for the particular value, including when `x` happens
>> to be zero (which doesn't really matter, because `x` is always an enum
>> value and never a magic number). You may ask the what is the
>> difference between "if (err)" and "if (err != success)" and it is that
>> the latter only tests for failure in the particular domain. Now, this
>> difference may not be obvious, and that is why I generally avoid
>> writing "if (err != success)".
> Yes, that would also be my expectation. So, if I understand your position
> correctly, you oppose to introducing yet another function `failure(ec)`, but
> you would be ok with fixing `if(ec)` so that it always means "failure" (of
> course provided that you can be convinced that there is anything that needs
Yes. Not actively opposed, though. I just don't see the point in
having this more verbose syntax for something that we already have and
that is more succint.
I'm not opposed to adding support for multiple success codes, quite
the opposite. My only condition is that this enhancement doesn't
penalize too much the existing usages with a single zero success code.
> It has been always my understanding that `error_code` is intended to be used
> so that the numeric value is always *exactly* the value returned by the
> system call: you do not change it, do not adapt it. You keep it unchanged so
> that when logged, the programmer can easily retrieve the original number say
> from the log file to check what went wrong with the system call. Instead,
> you use all this machinery with conditions to perform different queries, on
> what kind/sort of failure it was.
> Now, if you adapt the error code so that 0 means success and non-0 means
> failure, you are violating this idea that numeric value of `error_code`
> should be delivered unchanged, un-adapted.
Mapping foreign success codes to zero may be viewed as a hack, but in
practice it rarely matters. When you present error codes to the user,
you rarely want to present the numeric value. Most likely, you want to
present the human-readable result of `message()`, and it will be
produced using the mapped error code values.
I agree that ideally you would not have to map error codes, but that
is an acceptable compromise to have a decent performance and unified
syntax with the existing `std::error_code`. Hopefully, if we settle on
an efficient solution, we won't have to do this anymore.