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

### 832. Applying constexpr to System error support

Section: 19.5 [syserr] Status: NAD Submitter: Beman Dawes Opened: 2008-05-14 Last modified: 2016-01-28

Priority: Not Prioritized

View all other issues in [syserr].

View all issues with NAD status.

Discussion:

Initialization of objects of class `error_code` (19.5.4 [syserr.errcode]) and class `error_condition` (19.5.5 [syserr.errcondition]) can be made simpler and more reliable by use of the new `constexpr` feature [N2349] of C++0x. Less code will need to be generated for both library implementations and user programs when manipulating constant objects of these types.

This was not proposed originally because the constant expressions proposal was moving into the standard at about the same time as the Diagnostics Enhancements proposal [N2241], and it wasn't desirable to make the later depend on the former. There were also technical concerns as to how `constexpr` would apply to references. Those concerns are now resolved; `constexpr` can't be used for references, and that fact is reflected in the proposed resolution.

Thanks to Jens Maurer, Gabriel Dos Reis, and Bjarne Stroustrup for clarification of `constexpr` requirements.

LWG issue 804 is related in that it raises the question of whether the exposition only member `cat_` of class `error_code` (19.5.4 [syserr.errcode]) and class `error_condition` (19.5.5 [syserr.errcondition]) should be presented as a reference or pointer. While in the context of 804 that is arguably an editorial question, presenting it as a pointer becomes more or less required with this proposal, given `constexpr` does not play well with references. The proposed resolution thus changes the private member to a pointer, which also brings it in sync with real implementations.

[ Sophia Antipolis: ]

> On going question of extern pointer vs. inline functions for interface.

[ Pre-San Francisco: ]

> Beman Dawes reports that this proposal is unimplementable, and thus NAD.

> Implementation would require `constexpr` objects of classes derived from class `error_category`, which has virtual functions, and that is not allowed by the core language. This was determined when trying to implement the proposal using a constexpr enabled compiler provided by Gabriel Dos Reis, and subsequently verified in discussions with Gabriel and Jens Maurer.

Proposed resolution:

The proposed wording assumes the LWG 805 proposed wording has been applied to the WP, resulting in the former `posix_category` being renamed `generic_category`. If 805 has not been applied, the names in this proposal must be adjusted accordingly.

Change 19.5.3.1 [syserr.errcat.overview] Class `error_category` overview `error_category` synopsis as indicated:

>     const error_category& get_generic_category();
>     const error_category& get_system_category();

>     static extern const error_category&* const generic_category = get_generic_category();
>     static extern const error_category&* const native_category system_category = get_system_category();

Change 19.5.3.5 [syserr.errcat.objects] Error category objects as indicated:

>     extern const error_category&* const get_generic_category();

> Returns: A reference `generic_category` shall point to an a statically initialized object of a type derived from class `error_category`.

> Remarks: The object's `default_error_condition` and `equivalent` virtual functions shall behave as specified for the class `error_category`. The object's `name` virtual function shall return a pointer to the string `"GENERIC"`.

>     extern const error_category&* const get_system_category();

> Returns: A reference `system_category` shall point to an a statically initialized object of a type derived from class `error_category`.

> Remarks: The object's `equivalent` virtual functions shall behave as specified for class `error_category`. The object's `name` virtual function shall return a pointer to the string `"system"`. The object's `default_error_condition` virtual function shall behave as follows:

> If the argument `ev` corresponds to a POSIX `errno` value `posv`, the function shall return `error_condition(posv, generic_category)`. Otherwise, the function shall return `error_condition(ev, system_category)`. What constitutes correspondence for any given operating system is unspecified. [Note: The number of potential system error codes is large and unbounded, and some may not correspond to any POSIX `errno` value. Thus implementations are given latitude in determining correspondence. -- end note]

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

>     class error_code {
>     public:
>       ...;
>       constexpr error_code(int val, const error_category&* cat);
>       ...
>       void assign(int val, const error_category&* cat);
>       ...
>       const error_category&* category() const;
>       ...
>     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:

>     constexpr 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 as indicated:

>     class error_condition {
>     public:
>       ...;
>       constexpr error_condition(int val, const error_category&* cat);
>       ...
>       void assign(int val, const error_category&* cat);
>       ...
>       const error_category&* category() const;
>       ...
>     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:

>     constexpr 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.

Throughout 19.5 [syserr] System error support, change "`category().`" to "`category()->`". Appears approximately six times.

[Partially Editorial] In 19.5.6 [syserr.compare] Comparison operators, paragraphs 2 and 4, change "`category.equivalent(`" to "`category()->equivalent(`".

Change 19.5.8.1 [syserr.syserr.overview] Class system_error overview as indicated:

>     public:
>       system_error(error_code ec, const string& what_arg);
>       system_error(error_code ec);
>       system_error(int ev, const error_category&* ecat,
>           const string& what_arg);
>       system_error(int ev, const error_category&* ecat);

Change 19.5.8.2 [syserr.syserr.members] Class system_error members as indicated:

>     system_error(int ev, const error_category&* ecat, const string& what_arg);

> > Effects: Constructs an object of class `system_error`.

> > Postconditions: `code() == error_code(ev, ecat)` and `strcmp(runtime_error::what(), what_arg.c_str()) == 0`.

>     system_error(int ev, const error_category&* ecat);

> > Effects: Constructs an object of class `system_error`.

> > Postconditions: `code() == error_code(ev, ecat)` and `strcmp(runtime_error::what(), "") == 0`.

Rationale:

[ San Francisco: ]

> NAD because Beman said so.