Re: [boost] Reforming Boost.System and <system_error> round 2
On Wed, Jan 17, 2018 at 2:44 AM, Andrzej Krzemienski
2018-01-17 0:29 GMT+01:00 Andrey Semashev
: On Wed, Jan 17, 2018 at 1:16 AM, Andrzej Krzemienski via Boost
wrote: 2018-01-16 19:58 GMT+01:00 Andrey Semashev via Boost
: 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 fixing).
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.
participants (1)
-
Andrey Semashev