
Hi Peter, Peter Dimov <pdimov@mmltd.net> wrote:
The current intrerface gives priority to system error codes as evidenced by the single argument constructor. I could argue that we need to reverse that and give priority to errno, but another approach would be to just give the two equal standing with a from_sysno enum.
I would prefer that they are given equal weight, but as I've said elsewhere I also believe there's a need for other error categories.
It isn't clear why there is no error_code::message() const. Probably to not introduce a dependency on std::string and to avoid a copy. In my opinion, if you have to convert error codes to strings in an inner loop where the copy might be of any significance, you have already lost. :-) So I'd prefer the user-friendlier approach of
std::string error_code::message() const; std::wstring error_code::wmessage() const;
as people generally prefer members.
IMHO the error_code class should have fewer member functions, not more, and it should look more like a class that emulates a builtin type. However this line of thinking is probably driven by how I see this class being used wrt asio. Here's another thought: since POSIX strerror is defined to return a locale-dependent string, perhaps a C++ equivalent ought to use std::locale? (However, in practice this needs to be implemented on top of available system APIs, and I don't know if it's possible to implement std::locale-based functions in terms of setlocale().)
The introduction of operator== is also of questionable utility as it also forces us to prefer one of the two codes over the other.
If the constructors give equal weight to error types, then this would not be a problem. I think operator== and != are necessary because I would like to be able to define global error objects for the "well known" errors that can be returned by socket operations. E.g.: namespace boost { namespace asio { namespace error { extern const error_code eof; extern const error_code network_reset; extern const error_code operation_aborted; ... }}} These values would just be compared against the result of operations, as in: void handle_read(error_code ec) { if (ec == boost::asio::error::operation_aborted) ... } Whether the underlying error is an errno or a sysno isn't relevant to these use cases. Cheers, Chris