Document number: N3155=10-0145
Date: 2010-10-14
Author: J. Daniel Garcia
Project: Programming Language C++, Library Working Group
Reply To: josedaniel.garcia@uc3m.es

N3155 - More on noexcept for the language support library

During the Rapperswil meeting the Library Working Group decided to revise the library in terms of no except. This paper presents proposed wording for some of these changes. The paper addresses National Body comments CH 16 and GB 60.

This paper poposes additional changes to those presented in N3148, N3149 and N3150. Changes in this paper are restricted to chapter 18 (language support library).

All changes in this paper are against N3126.

Discussion

Start and termination functions

Exit functions _Exit() and abort() terminate without executing destructors for objects of automatic, thread, or static storage duration and without calling functions passed to atexit(). They are good candidates for noexcept as they will not be calling any functions being able to throw, as it is proposed in this paper.

atexit() functions may succeed or not in the registration action. In any case, they notify the failure by means of the return value. Thus, it is safe to make them noexcept. This also applies to at_quick_exit(). This paper proposes making all of them noexcept.

exit() function may throw, as it may destroy user defined objets and may call functions registered with i atexit(). Thus the cannot be make noexcept.

quick_exit() is not able to throw. It only calls to functions registered by means of at_quick_exit(). However, if a registered function throws an exception terminate is called. After that, it calls _Exit() which is also noexcept. This paper proposes to make it noexcept.

Class type_info

Class type_info are required to effectively store a pointer to a name for the type and and encoded value. Equallity comparisons are expected to be implemented in terms of the encoded value, which shouldn't throw. This is also applicable to ordering (before).

However, for member name() it may be necessary some (pontentially throwing) string management.

There is no reason that makes the destructor, potentially throwing.

Abnormal termination

Function terminate() cannot throw as it is called when exception handling must be abandoned.

Exception pointer management

make_exception_ptr() cannot throw. This may be inferred from the effects clause and the as-if code, where very exception is caught and no one is rethrown.

Nested exceptions

Member function nested_ptr() returns the stored exception pointer. This cannot throw.

Range access for initializer list

Functions begin() and end() are specified in terms of calling non-throwing begin() and end() member functions of initializer_list. Thus, they cannot throw.

Proposed Wording

18.5 Start and termination

After p. 2
[[noreturn]] void _Exit(int status) noexcept;
After p. 3
[[noreturn]] void abort(void) noexcept;
After p. 4
extern "C" int atexit(void (*f)(void)) noexcept;
extern "C++" int atexit(void (*f)(void)) noexcept;    
After p. 8
extern "C" int at_quick_exit(void (*f)(void)) noexcept;
extern "C++" int at_quick_exit(void (*f)(void)) noexcept;
After p. 11
[[noreturn]] void quick_exit(int status)noexcept

18.7.1 Class type_info

namespace std {
  class type_info {
  public:
    virtual ~type_info() noexcept;
    bool operator==(const type_info& rhs) const noexcept;
    bool operator!=(const type_info& rhs) const noexcept; 
    bool before(const type_info& rhs) const noexcept;
...
 };
}
After p. 1
bool operator==(const type_info& rhs) const noexcept;
After p. 3
bool operator!=(const type_info& rhs) const noexcept;
After p. 4
bool before(const type_info& rhs) const noexcept;

18.8 Exception handling

After p. 1
namespace std {
...
  [[noreturn]] void terminate() noexcept;
...
  template<class E> exception_ptr make_exception_ptr(E e) noexcept;
...
}

18.8.4.3 terminate

Before p. 1
[[noreturn]] void terminate() noexcept;

18.8.6 Exception Propagation

After p. 10
template<class E> exception_ptr make_exception_ptr(E e) noexcept;

18.8.7 nested_exception

Before p. 1
namespace std {
  class nested_exception {
  public:
...
  exception_ptr nested_ptr() const noexcept;
...
  };
}
After p. 4
exception_ptr nested_ptr() const noexcept;

18.9 Initializer lists

After p. 1
namespace std {
...
  // 18.9.3 initializer list range access
  template<class E> const E* begin(initializer_list<E> il) noexcept;
  template<class E> const E* end(initializer_list<E> il) noexcept;
}

18.9.3 Initializer list range access

Before p. 1
template<class E> const E* begin(initializer_list<E> il) noexcept;
After p. 1
template<class E> const E* end(initializer_list<E> il) noexcept;