Boost logo

Boost :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2006-02-21 11:21:33


Beman Dawes wrote:
> Peter Dimov wrote:
>
>> 1. system_error 'obviously' needs to derive from std::exception, but
>> whether it needs to derive from std::runtime_error isn't clear.
>
> Hum... I assumed that a system_error was 'obviously' a runtime error,
> and thus should be derived from std::runtime_error. What am I missing?

I'm thinking from client point of view here.

What catch clause do I need in order to handle system errors?

A. catch( system_error )

... if I want a system_error_code

B. catch( ??? )

... if I only want an errno code

C. catch( runtime_error )

... if I want ???

D. catch( exception )

... if I only want a what() string.

As you can see, there is one missing base, and derivation from runtime_error
doesn't add any value from client PoV.

>> 2. A constructor is provided for users to be able to construct a
>> system_error, but this constructor requires a string and doesn't
>> require a system error code. This is backwards; it is precisely the
>> system error code that makes a system_error distinct from a mere
>> runtime_error. Take it away, and it's not a system_error anymore. A
>> system_error should be constructible from a system error code, with
>> the library supplying an appropriate what() string.
>
> Yep. Fixed.

I think that

    explicit system_error( system_error_code_type ec );

should also work if I don't need to override the what() string. system_error
should be able to call FormatMessage or strerror for me.

Maybe

    explicit system_error( system_error_code_type ec, errno_type en = 0,
std::string const & what_arg = "" );

?

If we add the missing errno base:

class errno_exception: public std::exception
{
public:

    explicit errno_exception( errno_type en, std::string const & what_arg =
"" );
    errno_type errno_code() const;
};

and derive system_error from it, this would solve

>> 4. The proposed mechanism does not allow me to signal failure when
>> all I have is an errno value, since I have no way of translating
>> that back to a system error code.

Finally,

>> 5. Some system_errors can (and in some cases, ought to) be mapped to
>> existing exceptions, the most prominent example being ENOMEM, which
>> should be reported as std::bad_alloc.

this should probably be addressed via a convenience function:

void throw_system_error( system_error_code_type ec, errno_type en = 0,
std::string const & what_arg = "" );

that knows whether to throw bad_alloc or system_error to avoid the same
logic being replicated in every library.

I wonder whether it's possible to throw an exception on ENOMEM
(OUT_OF_MEMORY) that can be caught as either bad_alloc or system_error.
Perhaps not. std::exception would be an ambiguous base.


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