This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 116a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-12-19


1992. new (std::nothrow) int[N] can throw

Section: 7.6.2.8  [expr.new]     Status: CD4     Submitter: Martin Sebor     Date: 2014-08-27

[Adopted at the February, 2016 meeting.]

According to 7.6.2.8 [expr.new] paragraph 7,

If the expression, after converting to std::size_t, is a core constant expression and the expression is erroneous, the program is ill-formed. Otherwise, a new-expression with an erroneous expression does not call an allocation function and terminates by throwing an exception of a type that would match a handler (14.4 [except.handle]) of type std::bad_array_new_length (17.6.4.2 [new.badlength]).

This wording makes no provision for an expression like

  new (std::nothrow) int[N]

which most programmers would intuitively expect not to throw an exception under any condition.

Proposed resolution (May, 2015) [SUPERSEDED]:

Change the last part of 7.6.2.8 [expr.new] paragraph 7 as follows, converting the running text into bullets, and making the last sentence into a paragraph 8:

...If the expression, is erroneous after converting to std::size_t,:

When the value of the expression is zero, the allocation function is called to allocate an array with no elements.

Notes from the October, 2015 meeting:

The text in 15.4 paragraph 15 should also be changed.

Proposed resolution (January, 2016):

  1. Change 7.6.2.8 [expr.new] paragraph 7 as follows, dividing the running text into bullets and making the last sentence into a new paragraph:

  2. The expression in a noptr-new-declarator is erroneous if:

    If the expression, is erroneous after converting to std::size_t,:

    When the value of the expression is zero, the allocation function is called to allocate an array with no elements.

  3. Change 14.5 [except.spec] paragraph 14 as follows:

  4. The set of potential exceptions of an expression e is empty if e is a core constant expression (7.7 [expr.const]). Otherwise, it is the union of the sets of potential exceptions of the immediate subexpressions of e, including default argument expressions used in a function call, combined with a set S defined by the form of e, as follows:

    [Example:...

  5. Change the example in 14.5 [except.spec] bullet 17.2 as follows:

  6.   struct A {
        A(int = (A(5), 0)) noexcept;
        A(const A&) throw();
        A(A&&) throw();
        ~A() throw(X);
      };
      struct B {
        B() throw();
        B(const B&) = default; // exception specification contains no types
        B(B&&, int = (throw Y(), 0)) noexcept;
        ~B() throw(Y);
      };
      int n = 7;
      struct D : public A, public B {
        int * p = new (std::nothrow) int[n];
      // exception specification of D::D() contains X and std::bad_array_new_length
        // exception specification of D::D(const D&) contains no types
        // exception specification of D::D(D&&) contains Y
        // exception specification of D::~D() contains X and Y
      };
      struct exp : std::bad_alloc {};
      void *operator new[](size_t) throws(exp);
      struct E : public A {
        int * p = new int[n];
        // exception specification of E::E() contains X, exp, and std::bad_array_new_length
    };