<HTML>
<HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<TITLE>
    CWG Issue 1464</TITLE>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<STYLE TYPE="text/css">
  INS { text-decoration:none; font-weight:bold; background-color:#A0FFA0 }
  .INS { text-decoration:none; background-color:#D0FFD0 }
  DEL { text-decoration:line-through; background-color:#FFA0A0 }
  .DEL { text-decoration:line-through; background-color: #FFD0D0 }
  @media (prefers-color-scheme: dark) {
    HTML { background-color:#202020; color:#f0f0f0; }
    A { color:#5bc0ff; }
    A:visited { color:#c6a8ff; }
    A:hover, a:focus { color:#afd7ff; }
    INS { background-color:#033a16; color:#aff5b4; }
    .INS { background-color: #033a16; }
    DEL { background-color:#67060c; color:#ffdcd7; }
    .DEL { background-color:#67060c; }
  }
  SPAN.cmnt { font-family:Times; font-style:italic }
</STYLE>
</HEAD>
<BODY>
<P><EM>This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21
  Core Issues List revision 118b.
  See http://www.open-std.org/jtc1/sc22/wg21/ for the official
  list.</EM></P>
<P>2025-09-28</P>
<HR>
<A NAME="1464"></A><H4>1464.
  
Negative array bound in a <I>new-expression</I>
</H4>
<B>Section: </B>7.6.2.8&#160; [<A href="https://wg21.link/expr.new">expr.new</A>]
 &#160;&#160;&#160;

 <B>Status: </B>CD3
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>2012-02-12<BR>


<P>[Accepted at the April, 2013 meeting.]</P>



<P>Currently, 7.6.2.8 [<A href="https://wg21.link/expr.new#7">expr.new</A>] paragraph 7 requires that an
attempt to allocate an array with a negative length be diagnosed:</P>

<BLOCKQUOTE>

If the value of that <I>expression</I> is less than zero or such that
the size of the allocated object would exceed the
implementation-defined limit, or if the <I>new-initializer</I> is a
<I>braced-init-list</I> for which the number of
<I>initializer-clause</I>s exceeds the number of elements to
initialize, no storage is obtained and the <I>new-expression</I>
terminates by throwing an exception of a type that would match a
handler (14.4 [<A href="https://wg21.link/except.handle">except.handle</A>]) of type
<TT>std::bad_array_new_length</TT> (17.6.4.2 [<A href="https://wg21.link/new.badlength">new.badlength</A>]).

</BLOCKQUOTE>

<P>Checking for a negative bound will be lost, however, upon the
adoption of paper N3323, as the <I>expression</I> will be converted to
<TT>std::size_t</TT>, an unsigned type.  Although the result of this
conversion will likely also cause the check to fail (and will always
do so when scaled by an element size larger than 1), it is not
inconceivable that an implementation could provide a heap that capable
of providing more than half the addressable range of
<TT>std::size_t</TT>, and a request for a character array (with an
element size of 1) with a negative bound close to <TT>LONG_MIN</TT>
(assuming <TT>std::size_t</TT> is <TT>unsigned long</TT>) might
actually succeed.</P>

<P>The wording of 7.6.2.8 [<A href="https://wg21.link/expr.new#7">expr.new</A>] paragraph 7 should be
changed so that the test for a negative bound is applied to the
value before conversion to <TT>std::size_t</TT>, or some other
mechanism should be invented to preserve the check for a negative
bound.</P>

<P><B>Additional note (August, 2012):</B></P>

<P>The goal for addressing this issue should be that an attempt to use
an invalid bound (negative, greater than the maximum allowed, or more
than the number implied by the initializer) will be ill-formed when
the bound is a compile-time constant and will result in an exception
otherwise. </P>

<P><B>Proposed resolution (October, 2012):</B></P>

<OL>
<LI><P>Change 6.9.4 [<A href="https://wg21.link/basic.compound#2">basic.compound</A>] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

These methods of constructing types can be applied recursively;
restrictions are mentioned in 9.3.4.2 [<A href="https://wg21.link/dcl.ptr">dcl.ptr</A>], 9.3.4.5 [<A href="https://wg21.link/dcl.array">dcl.array</A>], 9.3.4.6 [<A href="https://wg21.link/dcl.fct">dcl.fct</A>], and 9.3.4.3 [<A href="https://wg21.link/dcl.ref">dcl.ref</A>]. <INS>Constructing a type such that the number of bytes
in its object representation exceeds the maximum value representable
in the type <TT>std::size_t</TT> (17.2 [<A href="https://wg21.link/support.types">support.types</A>]) is
ill-formed.</INS>

</BLOCKQUOTE>

<LI><P>Change 7.6.2.8 [<A href="https://wg21.link/expr.new#7">expr.new</A>] paragraph 7 as follows:</P></LI>

<BLOCKQUOTE>

<P><INS>The <I>expression</I> in a <I>noptr-new-declarator</I> is
erroneous if:</INS></P>

<UL>
<LI><P><INS>the expression is of non-class type and its value
before converting to <TT>std::size_t</TT> is less than
zero;</INS></P></LI>

<LI><P><INS>the expression is of class type and its value before
application of the second standard conversion (12.2.4.2.3 [<A href="https://wg21.link/over.ics.user">over.ics.user</A>]) [<I>Footnote:</I> If the conversion function
returns a signed integer type, the second standard conversion converts
to the unsigned type <TT>std::size_t</TT> and thus thwarts any attempt
to detect a negative value afterwards. &#8212;<I>end footnote</I>] is
less than zero;</INS></P></LI>

<LI><P><INS>its value is such that the size of the allocated object
would exceed the implementation-defined limit (annex Clause Annex B [<A href="https://wg21.link/implimits">implimits</A>]); or</INS></P></LI>

<LI>

<P>
<INS>the <I>new-initializer</I> is a <I>braced-init-list</I> and
the number of array elements for which initializers are provided
(including the terminating <TT>'\0'</TT> in a string literal
(5.13.5 [<A href="https://wg21.link/lex.string">lex.string</A>])) exceeds the number of elements to
initialize.</INS>
</P>
</LI>

</UL>
<P>
<INS>If the <I>expression</I>, after converting to
<TT>std::size_t</TT>, is a core constant expression and the expression
is erroneous, the program is ill-formed. Otherwise, a
<I>new-expression</I> 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 [<A href="https://wg21.link/except.handle">except.handle</A>]) of type
<TT>std::bad_array_new_length</TT> (17.6.4.2 [<A href="https://wg21.link/new.badlength">new.badlength</A>]).</INS> When the value of the <I>expression</I>
<DEL>in a <I>noptr-new-declarator</I></DEL> is zero, the allocation
function is called to allocate an array with no elements.  <DEL>If the
value of that <I>expression</I> is less than zero or such that the
size of the allocated object would exceed the implementation-defined
limit, or if the <I>new-initializer</I> is a
<I>braced-init-list</I> for which the number of
<I>initializer-clause</I>s exceeds the number of elements to
initialize, no storage is obtained and the <I>new-expression</I>
terminates by throwing an exception of a type that would match a
handler (14.4 [<A href="https://wg21.link/except.handle">except.handle</A>]) of type
<TT>std::bad_array_new_length</TT> (17.6.4.2 [<A href="https://wg21.link/new.badlength">new.badlength</A>]).</DEL>
</P>

</BLOCKQUOTE>

</OL>

<P>(This resolution also resolves <A HREF="1559.html">issue 1559</A>.)</P>

<BR><BR>
</BODY>
</HTML>
