This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of CD1 status.

### 804. Some problems with classes `error_code`/`error_condition`

Section: 19.5 [syserr] Status: CD1 Submitter: Daniel Krügler Opened: 2008-02-24 Last modified: 2016-01-28

Priority: Not Prioritized

View all other issues in [syserr].

View all issues with CD1 status.

Discussion:

1. 19.5.4.1 [syserr.errcode.overview]/1, class `error_code` and 19.5.5.1 [syserr.errcondition.overview]/, class `error_condition` synopses declare an expository data member `cat_`:

   >     const error_category& cat_; // exposition only

   which is used to define the semantics of several members. The decision to use a member of reference type lead to several problems:

   1. The classes are not `(Copy)Assignable`, which is probably not the intent.
   2. The post conditions of all modifiers from 19.5.4.3 [syserr.errcode.modifiers] and 19.5.5.3 [syserr.errcondition.modifiers], resp., cannot be fulfilled.

   The simple fix would be to replace the reference by a pointer member.

2. I would like to give the editorial remark that in both classes the constrained `operator=` overload (template with `ErrorCodeEnum` argument) makes in invalid usage of `std::enable_if`: By using the default value for the second `enable_if` parameter the return type would be defined to be `void&` even in otherwise valid circumstances - this return type must be explicitly provided (In `error_condition` the first declaration uses an explicit value, but of wrong type).
3. The member function `message` throws clauses ( 19.5.3.2 [syserr.errcat.virtuals]/10, 19.5.4.4 [syserr.errcode.observers]/8, and 19.5.5.4 [syserr.errcondition.observers]/6) guarantee "throws nothing", although they return a `std::string` by value, which might throw in out-of-memory conditions (see related issue 771).

[ Sophia Antipolis: ]

> Part A: NAD (editorial), cleared by the resolution of issue 832.

> Part B: Technically correct, save for typo. Rendered moot by the concept proposal (N2620) NAD (editorial).

> Part C: We agree; this is consistent with the resolution of issue 721.

> Howard: please ping Beman, asking him to clear away parts A and B from the wording in the proposed resolution, so it is clear to the editor what needs to be applied to the working paper.

> Beman provided updated wording. Since issue 832 is not going forward, the provided wording includes resolution of part A.

Proposed resolution:

Resolution of part A:

> Change 19.5.4.1 [syserr.errcode.overview] Class error_code overview synopsis as indicated:

> >     private:
> >       int val_;                    // exposition only
> >       const error_category&* cat_; // exposition only

> Change 19.5.4.2 [syserr.errcode.constructors] Class error_code constructors as indicated:

> >     error_code();

> > > Effects: Constructs an object of type `error_code`.

> > > Postconditions: `val_ == 0` and `cat_ == &system_category`.

> > > Throws: Nothing.

> >     error_code(int val, const error_category& cat);

> > > Effects: Constructs an object of type `error_code`.

> > > Postconditions: `val_ == val` and `cat_ == &cat`.

> > > Throws: Nothing.

> Change 19.5.4.3 [syserr.errcode.modifiers] Class error_code modifiers as indicated:

> >     void assign(int val, const error_category& cat);

> > > Postconditions: `val_ == val` and `cat_ == &cat`.

> > > Throws: Nothing.

> Change 19.5.4.4 [syserr.errcode.observers] Class error_code observers as indicated:

> >     const error_category& category() const;

> > > Returns: `*cat_`.

> > > Throws: Nothing.

> Change 19.5.5.1 [syserr.errcondition.overview] Class error_condition overview synopsis as indicated:

> >     private:
> >       int val_;                    // exposition only
> >       const error_category&* cat_; // exposition only

> Change 19.5.5.2 [syserr.errcondition.constructors] Class error_condition constructors as indicated:

> [ (If the proposed resolution of issue 805 has already been applied, the name `posix_category` will have been changed to `generic_category`. That has no effect on this resolution.) ]

> >     error_condition();

> > > Effects: Constructs an object of type `error_condition`.

> > > Postconditions: `val_ == 0` and `cat_ == &posix_category`.

> > > Throws: Nothing.

> >     error_condition(int val, const error_category& cat);

> > > Effects: Constructs an object of type `error_condition`.

> > > Postconditions: `val_ == val` and `cat_ == &cat`.

> > > Throws: Nothing.

> Change 19.5.5.3 [syserr.errcondition.modifiers] Class error_condition modifiers as indicated:

> >     void assign(int val, const error_category& cat);

> > > Postconditions: `val_ == val` and `cat_ == &cat`.

> > > Throws: Nothing.

> Change 19.5.5.4 [syserr.errcondition.observers] Class error_condition observers as indicated:

> >     const error_category& category() const;

> > > Returns: `*cat_`.

> > > Throws: Nothing.

Resolution of part C:

> In 19.5.3.2 [syserr.errcat.virtuals], remove the throws clause p. 10.

> >     virtual string message(int ev) const = 0;

> > > Returns: A string that describes the error condition denoted by `ev`.

> > > Throws: Nothing.

> In 19.5.4.4 [syserr.errcode.observers], remove the throws clause p. 8.

> >     string message() const;

> > > Returns: `category().message(value())`.

> > > Throws: Nothing.

> In 19.5.5.4 [syserr.errcondition.observers], remove the throws clause p. 6.

> >     string message() const;

> > > Returns: `category().message(value())`.

> > > Throws: Nothing.