A colleague mentioned that a problem he sees with
std::error_code is that you have to use 0 for success, which surprised me.
I couldn't see anything in the standard (looking at
[syserr]) that specifies this, except by intuition from the definition of
error_code::operator bool().
Assuming that the default constructor and clear() does leave both error_code and error_condition in the "no error" state, it seems slightly surprising that error_code::operator bool() doesn't check something like
*this == error_condition{};
Which would be unambiguously "no error" or "unset", irrespective of this->error_category(). It might be surprising from a performance perspective, hopefully compilers would reduce that down to only slightly worse than the current check for 0, and potentially optimising for system_category would bring the common-case back to unquestionably efficient.
The counter-example that got me thinking about this is the HTTP example from what appears to be the most-cited write-up for using these types, the blog post series "
System error support in C++0x", along with a note in a more recent blog post (by a different author)
"Your own error code", which was linked from the
isocpp.org front page recently.
Specifically, the latter blog post contains:
But our enumeration must meet one condition: numeric value 0 must not represent an error situation. 0 represents a success in any error domain (category). This expectation is later exploited when we are inspecting an std::error_code
object:1 2 3 4 5 6 7 | void inspect(std::error_code ec)
{
if (ec) // equivalent to: ec.value() != 0
handle_failure(ec);
else
handle_success();
}
|
In this sense the mentioned blog post has it incorrect that numeric value 200 indicates success.
This seems in conflict with the design intention expressed by
error_code, that it contain the unadulterated error number from the external or low-level system, e.g.,
[syserr.errcode.overview]
The class error_code describes an object used to hold error code values, such as those originating from the operating system or other low-level application program interfaces.
Since HTTP specifies that any result code from 200 to 299 indicates "success", it would seem reasonable at first-glance that an error_code containing something in that range would compare equal to std::error_condition{} if that was really all you cared about.
However, in that case, the boolean value as it stands now would be 'false', and the code-sample I have included would do the wrong thing.
This seems like an easy mistake to make, given the intuitive interpretation of if (error_code) as "if an error occurred".
Conversely, I can see a good argument that in an error_condition, 0 be always taken as "success", since by my understanding, we expect error_condition to isolate us from platform-specifics such as this.
It'd be nice if this was explicit in the standard itself, somehow, rather than relying on the same intuition that is being foiled above.