Boost logo

Boost :

From: Johan Nilsson (r.johan.nilsson_at_[hidden])
Date: 2006-11-15 06:37:54


Christopher,

Christopher Kohlhoff wrote:
> Hi Johan,
>
> Johan Nilsson <r.johan.nilsson_at_[hidden]> wrote:
>> "Should" is a strong word, IMHO.
>
> "Should" based on the guidelines discussed in this thread:
>
> http://lists.boost.org/Archives/boost/2006/02/101041.php
>

IIRC I've read that posting earlier - but was there ever a general
consensus? I can't find anything documented on boost.org.

Extract from that original posting:

<quote>
Guidelines:

   Unless otherwise specified, the default versions of all Boost library
   functions, except destructors, that call operating system API functions
   should check for API errors and report the occurrence of such errors by
   throwing an exception of type boost::system_error.

   Such functions should also have an overload that takes an additional
   argument of type boost::system_error_code& ec. The behavior of this
overload
   is the same as the non-overloaded version, except that it does not throw
an
   exception on an API error, and it sets ec to the error code reported by
the
   operating system, or to 0 if no error is reported.

   For functions where the non-overloaded version returns void, the
overloaded
   version returns an object of type boost::system_error_code with the same
   value that ec was set to.

</quote>

The second paragraph leads to the implementation being exposed through its
interface.

Generally I shouldn't have to care about whether a library function calls
down to an operating system API or not. Also, it might very well do so on
one platform but not on the other.

>> 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.
>
> I have a strong opinion that a TSS-based solution is error
> prone, since any function call can modify the TSS value as a
> side effect. I have seen the following sort of incorrect code
> many times:
>
> if (!SomeWindowsAPICall())
> {
> printf(
> "Error (%u): %s\n",
> GetLastError(),
> SomeOtherFunction());
> }

Me too. I would hope that reasonably experienced programmers don't do
something like that.

OTOH, usage of error_codes could also cause that kind of latent errors:

-----------
error_code const& foo(error_code& ec)
{
    if (!SomeWindowsAPICall())
    {
        return ec; // oops, forgot to set ec
    }

    ... do something ...
    ec = error_code(); // success

    return ec;
}
----------

As a side note: When writing the above, I believe error_code is missing a
"reset" or "clear" method.

>
> You might not find out that it's giving you the wrong error
> value until an obscure failure occurs at a customer site, and by
> that time it's too late :)

See above.

>
>> 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=).
>
> No, I see it as a bad thing to bless a TSS-based solution for
> error codes in C++ by putting it in a public interface, due to
> the error prone nature. It's not a "don't pay for what you don't
> use" issue for me.

I'm not "blessing" anything.

Also, the TSS-based suggestion had nothing to do with my "don't pay for what
you don't use" statement - that was only referring to the
Set/GetLastError/errno wrapper. Those might be TSS-based (or equivalently
implemented), but that was not my point.

Regards,
Johan


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