Title
Allocation with explicit alignment
Status
open
Section
7.6.2.8 [expr.new]
Submitter
Tim Song

Created on 2023-10-18.00:00:00 last changed 14 months ago

Messages

Date: 2023-10-18.00:00:00

Consider:

  #include <new>
  auto p = new (std::align_val_t{64}) T;

Is this example well-formed for T = int? This invokes the allocation function

  ::operator new(size_t, align_val_t);

If this is considered a "placement allocation function", the code is ill-formed per 7.6.2.8 [expr.new] paragraph 28, because deallocation function lookup finds a usual deallocation function. If this is considered a "usual allocation function", the rules find ::operator delete(void*) as the corresponding deallocation function.

There is implementation divergence: MSVC rejects; clang and gcc accept, but invoke ::operator delete(void*, align_val_t) if the constructor exits via an exception.

If T is a type with new-extended alignment, the preferred allocation function is operator new(std::size_t, std::align_val_t, std::align_val_t) or, as a fallback, operator new(std::size_t, std::align_val_t), removing the alignment information of T (7.6.2.8 [expr.new] paragraph 19).

As another concern, subclause 17.6.3.2 [new.delete.single] paragraph 11 disallows mixing aligned and unaligned allocation/deallocation functions, and implementations rely on that precondition. Thus, it is impossible to deallocate the memory obtained in the example using a delete-expression; an explicit deallocation function call appears to be required.

Possible resolution:

Disallow invocation of one of the allocation functions specified in 17.6.3.2 [new.delete.single] and 17.6.3.3 [new.delete.array] if the new-placement syntax is used with anything but a single expression of type std::nothrow_t.

Alternatively, make this conditionally-supported to offer a richer feature set on platforms where mixing aligned and unaligned allocation/deallocation works.

History
Date User Action Args
2023-10-18 00:00:00admincreate