Title
new (std::nothrow) int[N] can throw
Status
cd4
Section
8.3.4 [expr.new]
Submitter
Martin Sebor

Created on 2014-08-27.00:00:00, last changed 2017-02-06.00:00:00.

Messages

Date: 2016-01-15.00:00:00

Proposed resolution (January, 2016):

  1. Change 8.3.4 [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,:

    • if the expression is a core constant expression and the expression is erroneous, the program is ill-formed.;

    • Otherwise otherwise, a new-expression with an erroneous expression does not call an allocation function and is not called; instead

      • if the allocation function that would have been called has a non-throwing exception specification (18.4 [except.spec]), the value of the new-expression is the null pointer value of the required result type;

      • otherwise, the new-expression terminates by throwing an exception of a type that would match a handler (18.3 [except.handle]) of type std::bad_array_new_length (21.6.3.2 [new.badlength]).

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

  3. Change 18.4 [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 (8.20 [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:

    • ...

    • If e implicitly invokes a one or more functions (such as an overloaded operator, an allocation function in a new-expression, or a destructor if e is a full-expression (4.6 [intro.execution])), S is the set of potential exceptions of the function. union of:

      • the sets of potential exceptions of all such functions, and

      • if e is a new-expression with a non-constant expression in the noptr-new-declarator (8.3.4 [expr.new]) and the allocation function selected for e has a non-empty set of potential exceptions, the set containing std::bad_array_new_length.

    • ...

    • If e is a new-expression with a non-constant expression in the noptr-new-declarator (8.3.4 [expr.new]), S consists of the type std::bad_array_new_length.

    [Example:...

  5. Change the example in 18.4 [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
    };
    
Date: 2015-10-15.00:00:00

Notes from the October, 2015 meeting:

The text in 15.4 paragraph 15 should also be changed.

Date: 2015-05-15.00:00:00

Proposed resolution (May, 2015) [SUPERSEDED]:

Change the last part of 8.3.4 [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,:

  • if the expression is a core constant expression and the expression is erroneous, the program is ill-formed.;

  • Otherwise otherwise, a new-expression with an erroneous expression does not call an allocation function is not called; instead

    • if the allocation function that would have been called is non-throwing (18.4 [except.spec]), the value of the new-expression is the null pointer value of the required result type;

    • and otherwise, the new-expression terminates by throwing an exception of a type that would match a handler (18.3 [except.handle]) of type std::bad_array_new_length (21.6.3.2 [new.badlength]).

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

Date: 2016-02-15.00:00:00

[Adopted at the February, 2016 meeting.]

According to 8.3.4 [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 (18.3 [except.handle]) of type std::bad_array_new_length (21.6.3.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.

History
Date User Action Args
2017-02-06 00:00:00adminsetstatus: tentatively ready -> cd4
2016-02-15 00:00:00adminsetmessages: + msg5697
2016-02-15 00:00:00adminsetstatus: drafting -> tentatively ready
2015-11-10 00:00:00adminsetmessages: + msg5645
2015-11-10 00:00:00adminsetstatus: ready -> drafting
2015-05-25 00:00:00adminsetmessages: + msg5449
2015-05-25 00:00:00adminsetstatus: drafting -> ready
2014-08-27 00:00:00admincreate