Boost logo

Boost :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2006-06-27 09:36:17


Christopher Kohlhoff wrote:

> 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.

As long as there is at least one member, it's no longer a built-in-like. :-)

> 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().)

I think that messages are fine as-is. Their primary audience is people who
don't care about languages and locales (the same audience that finds what()
useful). Programmers who do care will create their own mapping tables based
on errno (or sysno, if they don't need portability for the error message
module).

>> 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.

It is.

The problem is that in general, there is no 1:1 mapping between sysno and
errno.

This means that in principle you can have error_codes e1, e2 and e3 such
that

e1.errno_value() == e2.errno_value() && e1.sysno_value() != e2.sysno_value()

and

e1.errno_value() != e3.errno_value() && e1.sysno_value() == e3.sysno_value()

so the current operator== does not imply equivalence.

> 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)
> ...
> }

Under implementation A, you'll get sysno's from the underlying low level
module, and the current operator== will do what you want. But under
implementation B you may get errno from the low level module (even though
the OS may have another sysno) and if two errno's map to the same sysno,
there is a problem. It may not be a practical problem, of course.

An operator== that compares both sysno_vaue() and errno_value() would allow
the above to work reliably, though... as long as there is a single sysno in
the OS, as you pointed out. :-)


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