2462. std::ios_base::failure is overspecified

Section: 31.5.2 [ios.base], 31.5.2.2.1 [ios.failure] Status: C++17 Submitter: Jonathan Wakely Opened: 2014-12-15 Last modified: 2023-02-07

Priority: 3

View all other issues in [ios.base].

View all issues with C++17 status.

Discussion:

31.5.2 [ios.base] defines ios_base::failure as a nested class:

namespace std {
  class ios_base {
  public:
    class failure;
    […]
  };
  […]
}

This means it is valid to use an elaborated-type-specifier to refer to ios_base::failure:

using F = class std::ios_base::failure;
throw F();

Therefore implementations are not permitted to define ios_base::failure as a typedef e.g.

 class ios_base {
 public:
#if __cplusplus < 201103L
   class failure_cxx03 : public exception {...};
   typedef failure_cxx03 failure;
#else
   class failure_cxx11 : public system_error {...};
   typedef failure_cxx11 failure;
#endif
   […]
 };

This constrains implementations, making it harder to manage the ABI change to ios_base::failure between C++03 and C++11.

[2015-05-06 Lenexa: Move to Ready]

JW: the issue is that users are currently allowed to write "class failure" with an elaborated-type-specifier and it must be well-formed, I want the freedom to make that type a typedef, so they can't necessarily use an elaborated-type-specifier (which there is no good reason to use anyway)

JW: ideally I'd like this everywhere for all nested classes, but that's a paper not an issue, I only need this type fixed right now.

RD: is a synonym the same as an alias?

JW: dcl.typedef says a typedef introduces a synonym for another type, so I think this is the right way to say this

JW: I already shipped this last month

PJP: we're going to have to break ABIs again some time, we need all the wiggle room we can get to make that easier. This helps.

MC: do we want this at all? Ready?

9 in favor, none opose or abstaining

Proposed resolution:

This wording is relative to N4296.

  1. Change the synopsis in 31.5.2 [ios.base] as indicated:

    namespace std {
      class ios_base {
      public:
        class failure; // see below
        […]
      };
      […]
    };
    
  2. Change 31.5.2 [ios.base] paragraph 1:

    ios_base defines several member types:

    • a class failuretype failure, defined as either a class derived from system_error or a synonym for a class derived from system_error;

  3. Change [ios::failure] paragraph 1:

    -1- An implementation is permitted to define ios_base::failure as a synonym for a class with equivalent functionality to class ios_base::failure shown in this subclause. [Note: When ios_base::failure is a synonym for another type it shall provide a nested type failure, to emulate the injected class name. — end note] The class failure defines the base class for the types of all objects thrown as exceptions, by functions in the iostreams library, to report errors detected during stream buffer operations.