Opened 12 years ago

Last modified 10 years ago

#5357 new Feature Requests

system::error_code::operator unspecified_bool_type() should not assume 0 == success.

Reported by: mgruenke@… Owned by: Beman Dawes
Milestone: To Be Determined Component: system
Version: Boost 1.45.0 Severity: Problem
Keywords: Cc: viboes

Description

[The following was submitted for discussion to boost@… on 2011-03-10. It received only one response, which was supportive.]

I've found boost.system to be very useful for wrapping return codes from 3rd party libraries (e.g. libcurl). However, one problem I've encountered is that error_code's operator for boolean tests assumes that an error value of 0 == success. While this is often true, it is not universally so and precludes use of boost.system for such tasks as wrapping HTTP status codes (several of which are merely informative and don't indicate an error).

I've found it puzzling that the logic for determining whether an error value represents an error doesn't reside in the error_category, where it can be customized as needed. For instance, boolean tests could chain to a is_error() virtual method in the error_category, the default implementation of which preserves the current behavior:

  namespace boost
  {
    namespace system
    {
      class error_category : public noncopyable
      {
      public:

        // ...

        virtual bool is_error( int ev ) const
        {
          return ev != 0;
        }

        // ...

      };


      class error_code
      {
      public:

        // ...

        operator unspecified_bool_type() const
        {
          return m_cat->is_error( m_val ) ? unspecified_bool_true : 0;
        }

        // ...

      };
    }
  }

Change History (4)

comment:1 by viboes, 10 years ago

Cc: viboes added

The code I'm seen in is

      operator unspecified_bool_type() const  // true if error
      { 
        return m_val == 0 ? 0 : unspecified_bool_true;
      }

It seems to me we can close this ticket now.

in reply to:  1 ; comment:2 by mgruenke@…, 10 years ago

Replying to viboes:

The code I'm seen in is

Yes, and that's the problem.

It seems to me we can close this ticket now.

Why is that? The problem has not been addressed.

in reply to:  2 ; comment:3 by viboes, 10 years ago

Replying to mgruenke@…:

Replying to viboes:

The code I'm seen in is

Yes, and that's the problem.

It seems to me we can close this ticket now.

Why is that? The problem has not been addressed.

Apologies. I didn't understood that the above code was related to a change proposal.

IIUC, you pretend that the proposed change behavior is compatible with the C++11 standard. I don't think this is the case.

A generic library using the current error_code behavior would break when instantiated with an error_category that refines the is_error behavior. So that this is a breaking change that needs more careful documentation.

I will suggest you to post to the std-discussion ML this possible enhancement.

in reply to:  3 comment:4 by mgruenke@…, 10 years ago

Replying to viboes:

IIUC, you pretend that the proposed change behavior is compatible with the C++11 standard. I don't think this is the case.

Pretend is a strong word. In fact, I made no statement about C++11.

On that subject, I think Boost is Boost and the standard library is the standard library. I don't see why Boost can't offer more than what's provided by the standard library, even if it was influenced by a corresponding feature in Boost.

A generic library using the current error_code behavior would break when instantiated with an error_category that refines the is_error behavior.

How would it break? A given bit of code is either using a boost::system::error_code or a std::error_code. They're different types, and whichever is being used, the compiler will correctly instantiate the corresponding check.

I will suggest you to post to the std-discussion ML this possible enhancement.

Last I checked, this was the boost library bug tracker. If the standard library adopted this problematic behavior, I think that's unfortunate but probably too late to change.

However, so long as there's boost::system, an option could exist for those cases where success does not map uniquely to 0. That's why I think this is worth fixing, regardless of what's in the standard library.

Note: See TracTickets for help on using tickets.