This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 119a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2025-12-20
[Adopted at the February, 2016 meeting.]
According to 7.6.2.8 [expr.new] paragraph 7,
If the expression, after converting tostd::size_t, is acore constant expression and the expression is erroneous,the program is ill-formed. Otherwise,anew-expression with an erroneous expression doesnot call an allocation function and terminates by throwingan exception of a type that would match a handler(14.4 [except.handle]) of typestd::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 throwan exception under any condition.
Proposed resolution (May, 2015) [SUPERSEDED]:
Change the last part of7.6.2.8 [expr.new] paragraph 7 as follows,converting the running text into bullets, and making thelast sentence into a paragraph 8:
...If the expression
,is erroneousafter converting tostd::size_t,:
if theexpression is a core constantexpression
and the expression is erroneous, the program isill-formed.;
Otherwiseotherwise,anew-expression with an erroneous expression doesnot callan allocation functionis not called;instead
if the allocation function that would have beencalled is non-throwing (14.5 [except.spec]), the valueof thenew-expression is the null pointer value of therequired result type;
andotherwise, thenew-expression terminates by throwing anexception of a type that would match a handler(14.4 [except.handle]) of typestd::bad_array_new_length(17.6.4.2 [new.badlength]).When the value of theexpression is zero, theallocation function is called to allocate an array with noelements.
Notes from the October, 2015 meeting:
The text in 15.4 paragraph 15 should also be changed.
Proposed resolution (January, 2016):
Change 7.6.2.8 [expr.new] paragraph 7 asfollows, dividing the running text into bullets and makingthe last sentence into a new paragraph:
The expression in anoptr-new-declarator is erroneousif:
...
If theexpression
,iserroneous after convertingtostd::size_t,:
if theexpression is a coreconstant expression
and the expression iserroneous, the program isill-formed.;
Otherwiseotherwise,anew-expression with an erroneous expression doesnot callan allocation functionandis not called; instead
if the allocation function that would have beencalled has a non-throwing exception specification(14.5 [except.spec]), the value of thenew-expression is the null pointer value of the requiredresult type;
otherwise, thenew-expressionterminates by throwing an exception of a type that wouldmatch a handler (14.4 [except.handle]) of typestd::bad_array_new_length(17.6.4.2 [new.badlength]).
When the value of the expression is zero, the allocationfunction is called to allocate an array with noelements.
Change 14.5 [except.spec] paragraph 14 as follows:
Theset of potential exceptions of anexpressione is empty if e is a core constantexpression (7.7 [expr.const]). Otherwise, it is theunion of the sets of potential exceptions of the immediatesubexpressions ofe, including default argument expressionsused in a function call, combined with a setS defined bythe form of e, as follows:
...
Ife implicitly invokes
aone ormore functions (such as an overloadedoperator, an allocation function in anew-expression,or a destructor ife is a full-expression(6.10.1 [intro.execution])),S is theset ofpotential exceptions of the function.unionof:
the sets of potential exceptions of all suchfunctions, and
ife is anew-expression with anon-constantexpression in thenoptr-new-declarator (7.6.2.8 [expr.new]) andthe allocation function selected fore has anon-empty set of potential exceptions, the set containingstd::bad_array_new_length.
...
Ife is anew-expression with a non-constantexpression in thenoptr-new-declarator(7.6.2.8 [expr.new]),S consists of the typestd::bad_array_new_length.[Example:...
Change the example in 14.5 [except.spec]bullet 17.2 as follows:
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 ofD::D() containsXandstd::bad_array_new_length // exception specification ofD::D(const D&) contains no types // exception specification ofD::D(D&&) containsY // exception specification ofD::~D() containsX andY }; struct exp : std::bad_alloc {}; void *operator new[](size_t) throws(exp); struct E : public A { int * p = new int[n]; // exception specification ofE::E() containsX,exp, andstd::bad_array_new_length};