|
Boost : |
From: Beman Dawes (bdawes_at_[hidden])
Date: 2006-11-13 17:56:46
Johan Nilsson wrote:
> Beman Dawes wrote:
>> On 11/8/06, Johan Nilsson <r.johan.nilsson_at_[hidden]> wrote:
>
> [snip]
>
>>> I'm trying to find the documentation for the Boost.System stuff -
>>> any pointers?
>>>
>> In the CVS Head, see libs/system/doc/error_code.html, and
>> libs/system/doc/system_error.html
>>
>> Also see
>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2066.html
>
> Ok, so I've made a quick pass though the docs. A few questions and
> comments:
>
> 1) Are there any guarantees for the lifetime of the decoder
> references as returned by error_code::get_decoders?
The pointers are assigned to the references, so it doesn't matter if the
references themselves are to ephemeral (automatic or head) storage.
> Could I hold on to them "forever", once retrieved?
yes, you can hold onto the pointers "forever".
> 2) I've implemented similar code previously, but only designed for
> portability with linux and Win32. What I very often use, is something
> corresponding to retrieving errno or calling GetLastError (on
> Win32).
The C++ committee's Library Working Group is discussing making low-level
functionality like that more generally available. It would be easy
to implement.
> With the current design, it is harder to implement library code
> throwing system_errors (retrieving error codes) as you'll need to get
> the corresponding error code in a platform-specific way. Or did I
> miss something?
>
> I'd like something like this in the error_code interface:
>
> class error_code { ... static error_code
> last_error_code(error_category const& ecat); static void
> last_error_code(error_category const& ecat, error_code::value_type
> new_error_code); ... };
>
> Which would enable:
>
> throw system_error(error_code::last_error_code(native_ecat),
> "Failed!");
>
> of perhaps even:
>
> throw last_system_error("Failed!");
>
> I know it's not 100% natively portable, as e.g. OpenVMS does not have
> an equivalent of Set/GetLastError - but at least using errno_ecat
> should be universal, and using native_ecat could be implementation
> defined (or simply use errno internally when nothing else is
> available).
Not quite sure what you mean here. All functions calling operating
system API's either throw exceptions containing an error_code, or have
non-throwing versions that return the error_code via an argument. So
those cases are covered.
If you are implementing your own library, presumably you are calling
operating system dependent API's anyhow, so calling the operating
system's "get last error" function shouldn't be a problem.
> 3) Don't the static methods new_category and get_decoders belong to
> the error_category interface, rather than error_code?
Good question. Or maybe free functions. I'll give it some thought.
> 4) I'm wondering about best practices for how to use the error_code
> class portably while maintaining as much of the (native) information
> as possible. Ideally, it should be possible to check for specific
> error codes portably, while having the native descriptions(messages)
> available for as much details as possible. Using native_ecat and
> compare using to_errno?
Library functions should always report errors via the exact error_code
value and category reported by the operating system API call that
failed. That way no information is lost. Usually this will be the
native_ecat (which is the same as the errno_ecat on POSIX systems), but
for some networking calls it may be some other error category.
The user of the library function has a choice. If interested in the
exact error as reported, they can test directly. Otherwise, to write
portable code, they can use to_errno().
>
> 5) Ideally, I think having error_code as an additional part of
> std::runtime_error instead of having the separate system_error class
> would make sense.
system_error is derived from std::runtime_error.
> A error_code feels more like a property of a
> runtime_error that might or might not be set. Might not be practical
> though.
If the error_code were part of the state of runtime_error rather than
system_error, all uses of runtime_error would have to pay the
(admittedly small) cost of having an error_code in each runtime_error
object, even though only used for errors that have an associated error code.
> 6) A "std::string error_category::description() const" method feels
> like a good idea to add. Don't ask me for any specific reasons just
> yet.
How is that better than what()?
> 7) The error_category management seems very simplistic, just a static
> new_category(...) method. Did you think anything more about the
> management? It is not very unlikely that independent components will
> need to use (and therefore also add) the "same" category (e.g.
> winsock_category, nt_native_category, getaddrinfo_category, ...).
> Would it be possible somehow to access information on available
> error_categories to be able to avoid insertion of new
> error_categories with equal properties? Just thinking out loud here
> ...
Yes, I guess so. I'll give it some thought.
> 8) An enumeration (or class with static constants) containing the
> available standard posix error codes (as referenced in the docs)
> would be nice, e.g. posix_error::xxx_errno, posix_error::yyy_errno,
> ...
>
> 9) I assume the category management is thread-safe. I saw nothing
> explicit about that in the docs.
>
> 10) I'd also like an explicit guarantee that the implementations of
> error_category/system_error/error_code should be error neutral -
> i.e., that they don't affect the current values of e.g errno and
> GetLastError.
>
> 11) With reference to 10 above - a useful addition to the library
> would be an "error_code_preserver" class, a RAII class that picks up
> the current error code when created, and restores it on destruction.
> Very useful when you want to implement your own error-neutral
> functionality (such as in e.g. a logging framework). Perhaps nothing
> for the standard, but why not for Boost.System?
I'll also give those three some thought:-)
> BTW, if you have implemented error_code::to_errno for native_ecat on
> Win32, consider me suitably impressed.
Nothing to be impressed about. It is just a "best guess" lookup table
for the small number of errno values actually encountered by common API
calls. Everything else just gets tossed into a catch-all code.
> Overall, this is for a very much awaited addition to Boost (and even
> more so to the C++ standard, eventually). Looking forward to use it!
Thanks!
--Beman
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk