Is new T[0] required to return a unique pointer?

145 views
Skip to first unread message

Herb Sutter

unread,
Aug 7, 2012, 10:58:59 PM8/7/12
to std-dis...@isocpp.org, James Y Knight

Is this assert guaranteed to succeed, at least if T uses the default allocator?

 

  T* p1 = new T;

  T *p2 = new T[0];

  assert( p1 != p2 );   // is this guaranteed?

 

In an article some years ago, I quoted the following from evidently some non-standard draft of 5.3.4/7, but the [Note] is not in the current standard:

 

> When the value of the expression in a direct-new-declarator is zero, the

> allocation function is called to allocate an array with no elements. The

> pointer returned by the new-expression is non-null. [Note: If the library

> allocation function is called, the pointer returned is distinct from the

> pointer to any other object.]

 

Neither James nor I can find current text – is this still guaranteed? If so, where does the standard say so?

 

And are replacement allocators allowed to return non-unique pointers in this case?

 

Thanks,

 

Herb

 

 

Jean-Marc Bourguet

unread,
Aug 8, 2012, 4:12:27 AM8/8/12
to std-dis...@isocpp.org, James Y Knight, hsu...@microsoft.com
I know we have code relying on this. So I digged further to ensure we are correct to do so. Your quote has been deleted in C++2003 (has part of lib 9 according to the annotated version of C++ 2003 I'm using, but I can't find an issue 9 in the issue list). It has been replaced by language in [lib.new.delete]

Except where otherwise specified, the provisions of (3.7.3) apply to the library versions of operator new and operator delete.

and in [basic.stc.dynamic.allocation]/2

Even if the size of the space requested is zero, the request can fail. If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from any previously returned value p1, unless
that value p1 was subsequently passed to an operator delete.

This is slightly different. The deleted note seems to prevent ptr == &x in the following context while the current language seems to allow it.


int x;
int* ptr = new int[0];


Replacement are constrained by18.6.1.1 :

Return a non-null pointer to suitably aligned storage (3.7.4), or else throw a bad_alloc exception. This requirement is binding on a replacement version of this function.

and

Any allocation and/or deallocation functions defined in a C++ program, including the default versions in the library, shall conform to the semantics specified in 3.7.4.1 and 3.7.4.2.


basic.stc.dynamic.allocation is 3.7.3 in c++ 2003 and 3.7.4 in c++2011. (lib.)new.delete is 18.4 in c++ 2003 and 18.6 in c++2011. I fear I've quoted from both. I'm not aware of substential difference.

So I don't think that replacement allocators are allowed to return non-unique pointers.

Yours,

--
Jean-Marc

Johannes Schaub

unread,
Aug 11, 2012, 2:13:32 PM8/11/12
to std-dis...@isocpp.org, James Y Knight, hsu...@microsoft.com


On Wednesday, August 8, 2012 4:58:59 AM UTC+2, Herb Sutter wrote:

Is this assert guaranteed to succeed, at least if T uses the default allocator?

 

  T* p1 = new T;

  T *p2 = new T[0];

  assert( p1 != p2 );   // is this guaranteed?

 


The C++ object model gives this guarantee at 1.8p6:

"Two objects that are not bit-fields may have the same address if one is a subobject of the other, or if at least one is a base class subobject of zero size and they are of different types; otherwise, they shall have distinct addresses."

So both the object of type "T[0]" and the object of type "T" shall have distinct addresses.

Johannes Schaub

unread,
Aug 11, 2012, 3:50:10 PM8/11/12
to std-dis...@isocpp.org, James Y Knight, hsu...@microsoft.com


On Wednesday, August 8, 2012 4:58:59 AM UTC+2, Herb Sutter wrote:

Is this assert guaranteed to succeed, at least if T uses the default allocator?

 

  T* p1 = new T;

  T *p2 = new T[0];

  assert( p1 != p2 );   // is this guaranteed?

 

In an article some years ago, I quoted the following from evidently some non-standard draft of 5.3.4/7, but the [Note] is not in the current standard:

 


You may also be interested in the following post, which also concerns the object model with regard to T[0]: https://groups.google.com/forum/#!msg/comp.lang.c++.moderated/sLmBrk04Alk/xAspy1U3CpQJ%5B1-25%5D 
Reply all
Reply to author
Forward
0 new messages