At what point does the lifetime of a trivial type created by placement-new start?

旧巷老猫 提交于 2019-12-06 01:08:17

问题


During a dive into dynamic memory, it occurred to me it appears contradictory how trivial types begin their lifetime. Consider the snippet

void* p = ::operator new(sizeof(int));  // 1
// 2
new (p) int; // 3

When does the int start its lifetime?

  1. Only acquires storage, ::operator new is specified to have the effect (from [new.delete.single])

    The allocation functions called by a new-expression to allocate size bytes of storage. [...] allocates storage suitably aligned to represent any object of that size provided the object's type does not have new-extended alignment.

    Given that acquiring storage is insufficient in creating an object, the int cannot have begin its lifetime here.

  2. At this point, suitbale storage for the int has been acquired.

  3. The int is created by placement new. But somehow its lifetime didn't begin here, since from [basic.life]

    [...] An object is said to have non-vacuous initialization if it is of a class or aggregate type and it or one of its subobjects is initialized by a constructor other than a trivial default constructor. The lifetime of an object of type T begins when:

    • storage with the proper alignment and size for type T is obtained, and

    • if the object has non-vacuous initialization, its initialization is complete [...]

    int is neither a class nor aggregate type, hence it has vacuous initialization. Therefore only the first bullet applies. However, this is clearly not when storage is obtained and therefore cannot be when its lifetime starts.

Some context

Allocators are required to return memory without constructing its elements. Yet this doesn't make sense with trivial types. The effects of a.allocate(n) with a an allocator object for type T is

Memory is allocated for n objects of type T but objects are not constructed.


回答1:


Technically, the new-expression always obtains storage. The code new(p) int both obtains storage and creates an object, and according to [basic.life]/1, the object's lifetime began when new(p) int obtained the storage.

According to N4659 [expr.new], the code new(p) int generates a call to an allocation function ::operator new(sizeof(int), p). And under [new.delete.placement], the standard library defines such a function:

void* operator new(std::size_t size, void* ptr) noexcept;

Returns: ptr.

Remarks: Intentionally performs no other action.

Although "no other action" is performed, and probably the implementation will optimize out any actual function call, this call to an allocation function still counts as obtaining storage for the object being created by the new-expression.



来源:https://stackoverflow.com/questions/49038246/at-what-point-does-the-lifetime-of-a-trivial-type-created-by-placement-new-start

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!