Re: [boost] [system] Was: Re: [asio] Breaking changes committed to cvs HEAD

Johan Nilsson <r.johan.nilsson@gmail.com> wrote:
Imagine that you're implementing a "middle-layer" library, calling down to "lower-layer" methods that do the actual O/S specific calls. The lower-layer methods might be C methods, or a third-party library.
Examples for comparison: [...]
In my experience the lower layer tends to look more like: void foo() { error_code ec; foo(ec); // Called foo_impl() in your examples if (ec) throw system_error(ec); } error_code foo(error_code& ec) { #ifdef BOOST_WINDOWS ... windows implementation ... ec = error_code(::GetLastError(), native_ecat); #else ... posix implementation ... ec = error_code(errno, native_ecat); #endif return ec; } At least, this is my understanding of how error_code and system_error should be used. IMHO if the lowest level wrappers use the error_code class in this way, there's no need for a publicly available wrapper for ::GetLastError()/errno. Having said that, I do have some "portable" helper functions inside of asio to do effectively what you're proposing, However they're only truly useful on a subset of the functions and are mostly a hangover from before I switched asio to use error_code/system_error. See clear_error() and error_wrapper() in this file: http://boost.cvs.sourceforge.net/*checkout*/boost/boost/boost/asio/detail/so... Cheers, Chris

Christopher Kohlhoff wrote:
Johan Nilsson <r.johan.nilsson@gmail.com> wrote:
Imagine that you're implementing a "middle-layer" library, calling down to "lower-layer" methods that do the actual O/S specific calls. The lower-layer methods might be C methods, or a third-party library.
Examples for comparison: [...]
In my experience the lower layer tends to look more like:
void foo() { error_code ec; foo(ec); // Called foo_impl() in your examples if (ec) throw system_error(ec); }
error_code foo(error_code& ec) { #ifdef BOOST_WINDOWS ... windows implementation ... ec = error_code(::GetLastError(), native_ecat); #else ... posix implementation ... ec = error_code(errno, native_ecat); #endif return ec; }
There's still code duplication here, which might or might not be possible to get rid of depending on what actually could be hiding in the "... <os> implementation ..." parts.
At least, this is my understanding of how error_code and system_error should be used.
"Should" is a strong word, IMHO. I find the usage of error_code as a parameter to methods pollutes the domain interfaces and make them more complex. I'd probably prefer a TSS-based solution.
IMHO if the lowest level wrappers use the error_code class in this way, there's no need for a publicly available wrapper for ::GetLastError()/errno.
That's a big if. If we had this facility, I could use it and you could still not use it. You, as a user, don't need to pay for what you don't need. (Also, you're missing out the modifying wrappers for SetLastError, errno=). I feel this is similar to saying that there's no need for the std facility "foo", as you can use the native "foo" functionality at the lowest level. Isn't this all about making usage of common functionality more streamlined/portable?
Having said that, I do have some "portable" helper functions inside of asio to do effectively what you're proposing,
There it is. That makes us at least two people who have written their own similar functionality ;-)
However they're only truly useful on a subset of the functions and are mostly a hangover from before I switched asio to use error_code/system_error.
Many subsets in many libraries end up with a pretty big "user" base. The general usefulness would also depend on the interface of the helpers. I respect your opinions, but I don't agree with you. Regards / Johan
participants (2)
-
Christopher Kohlhoff
-
Johan Nilsson