What is the value of pointer returned by an allocation function?

81 views
Skip to the first unread message

Language Lawyer

unread,
20 July 2018, 2:49:21 pm20/7/18
to std-dis...@isocpp.org
Every value of pointer type is one of the following:
— a pointer to an object or function (the pointer is said to point to the object or function), or
—a pointer past the end of an object ([expr.add]), or
— the null pointer value ([conv.ptr]) for that type, or
— an invalid pointer value.
(from http://eel.is/c++draft/basic.compound#3)

An allocation function attempts to allocate the requested amount of storage.
If it is successful, it returns the address of the start of a block of storage whose length in bytes is at least as large as the requested size.
(from http://eel.is/c++draft/basic.stc.dynamic#allocation-2)

What is the value of the pointer returned by an allocation function? Is a block of storage an object?

Richard Smith

unread,
20 July 2018, 3:39:36 pm20/7/18
to std-dis...@isocpp.org
We currently have something of a wording hole here. Under P0593, objects will be implicitly created in the storage pointed to by the pointer returned by operator new / operator new[]. The idea is that you can then treat it as a pointer to an array of the requested size of unsigned char / std::byte (though perhaps we should also say that the pointer is "adjusted" to actually point to the implicitly created object in that case) -- and that it doesn't matter what the pointer "points to" within the allocation function; all that matters is what address it represents. The idea is that you can do things like this:

int *p = (int*)operator new(sizeof(int), align_val_t(alignof(int)));
*p = 123; // ok, implicitly created an 'int' object (and adjusted returned pointer to point to it) as part of calling 'operator new'

... for implicit lifetime types.

cpplj...@gmail.com

unread,
21 July 2018, 3:51:06 am21/7/18
to ISO C++ Standard - Discussion
Where "implicit lifetime types" are as defined  in section 1 of p0593r2, I assume.
But for non-implicit lifetime types, it's just a void* to uninitalized storage?
 

Language Lawyer

unread,
21 July 2018, 4:54:26 am21/7/18
to std-dis...@isocpp.org
> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0593r2.html>, I
> assume.
> But for non-implicit lifetime types, it's just a void* to uninitalized
> storage?

I assume "implicit lifetime types" is an informal synonym for
objects without non-vacuous initialization
(http://eel.is/c++draft/basic.life#def:initialization,non-vacuous)

Nicol Bolas

unread,
21 July 2018, 9:40:14 am21/7/18
to ISO C++ Standard - Discussion
No, that's different.

"Implicit lifetime type" is a property of a type. A class or built-in type either has or doesn't have this property.

Vacuous initialization is a property of the initialization of an object. It is not a property of the type of that object. Asking the question of whether `int` does or does not have vacuous initialization is like asking if a type is a subobject. Types aren't subobjects, and neither do types have vacuous initialization.

The statement `int i;` initializes `i` vacuously. The statement `int i = 10;` does not.

Nicol Bolas

unread,
21 July 2018, 9:41:30 am21/7/18
to ISO C++ Standard - Discussion
Wait: I remember that passage incorrectly; built-in types and enumerations apparently always have vacuous initialization.

Language Lawyer

unread,
22 July 2018, 7:54:01 am22/7/18
to std-dis...@isocpp.org
On 21/07/18 16:40, Nicol Bolas wrote:
>
>
> On Saturday, July 21, 2018 at 4:54:26 AM UTC-4, Language Lawyer wrote:
>>
> Vacuous initialization is a property of the *initialization* of an *object*.

Y, you are right, I have read [basic.life] not carefully enough.

cpplj...@gmail.com

unread,
23 July 2018, 6:14:08 pm23/7/18
to ISO C++ Standard - Discussion, cpplj...@gmail.com
Maybe I should have been more explcit.  I'm asking if, instead of:

  int *p = (int*)operator new(sizeof(int), align_val_t(alignof(int)));

the statement was:

  non_impl_life_t *p = (non_impl_life_t*)operator new(sizeof(non_impl_life_t), align_val_t(alignof(non_impl_life_t)));
  *p=non_impl_life_t();

where non_impl_life_t is some type that is *not* an implicit lifetime type, then the value returned by the
allocation function would uninitialized storage and the deref and assignment in 2nd line would be undefined.

Hmm.  Maybe p0593r intends that in both the int and the non_impl_life_t examples, the value return by the allocation
function (i.e. new) is uninitialized storage, but in the int case, the compiler would look at the deref & assignment and
at that point *would* initialize the storage to be an int, making the 2nd statement defined behaviour?

Could somebody please clarify?

-regards,
Larry


Language Lawyer

unread,
23 July 2018, 6:24:52 pm23/7/18
to std-dis...@isocpp.org
>> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0593r2.html>, I
>> assume.
>> But for non-implicit lifetime types, it's just a void* to uninitalized
>> storage?
>>
>>
> Maybe I should have been more explcit. I'm asking if, instead of:
>
> int *p = (int*)operator new(sizeof(int), align_val_t(alignof(int)));
>
> the statement was:
>
> non_impl_life_t *p = (non_impl_life_t*)operator
> new(sizeof(non_impl_life_t), align_val_t(alignof(non_impl_life_t)));
> *p=non_impl_life_t();
>
> where non_impl_life_t is some type that is *not* an implicit lifetime type,
> then the value returned by the
> allocation function would uninitialized storage and the deref and
> assignment in 2nd line would be undefined.
>
> Hmm. Maybe p0593r intends that in both the int and the non_impl_life_t
> examples, the value return by the allocation
> function (i.e. new) is uninitialized storage, but in the int case, the
> compiler would look at the deref & assignment and
> at that point *would* initialize the storage to be an int, making the 2nd
> statement defined behaviour?

This is very close to what p0593 propose:
"""
Therefore we propose the following rule:

Some operations are described as implicitly creating objects within a specified region of storage. The abstract machine creates objects of implicit lifetime types within those regions of storage as needed to give the program defined behavior. For each operation that is specified as implicitly creating objects, that operation implicitly creates zero or more objects in its specified region of storage if doing so would give the program defined behavior. If no such sets of objects would give the program defined behavior, the behavior of the program is undefined.
"""

Although, assignment doesn't seem to be in the list of operations implicitly creating objects.
Reply all
Reply to author
Forward
0 new messages