The relevant paragraph is [basic.stc.dynamic.allocation]/3 (emphasis mine):
(3) For an allocation function other than a reserved placement allocation function, the pointer returned on a successful call shall represent the address of storage that is aligned as follows:
(3.1) — If the allocation function takes an argument of typestd::align_val_t
, the storage will have the alignment specified by the value of this argument.
(3.2) — Otherwise, if the allocation function is namedoperator new[]
, the storage is aligned for any object that does not have new-extended alignment and is no larger than the requested size.
(3.3) — Otherwise, the storage is aligned for any object that does not have new-extended alignment and is of the requested size.
My understanding is as follows:
Both the single-object and the array forms of alignment-unaware allocation functions cap the guaranteed alignment to __STDCPP_DEFAULT_NEW_ALIGNMENT__
.
With that constraint, and assuming __STDCPP_DEFAULT_NEW_ALIGNMENT__ == 8u
:
- The single-object form aligns for any object of the requested size. Thus, a request of 4 bytes would only guarantee 4-byte-aligned storage, as an 8-byte-aligned object would be at least 8 bytes in size. A 3-byte request would only guarantee 1-byte alignment, as an object with any stricter alignment could not be 3 bytes in size. (An object’s size is a (non-zero) multiple of its alignment requirement (
sizeof(x) % alignof(decltype(x)) == 0
).) - The array form aligns for any object no larger than the requested size. Thus, a request of 4 bytes would only guarantee 4-byte-aligned storage (as above), but a 3-byte request would guarantee 2-byte alignment, as a 2-byte-aligned object could be only 2 bytes in size.
The array form must therefore satisfy alignment requirements for a superset of objects for which the single-object form must satisfy such requirements. In other words, the post-conditions of the former subsume those of the latter. Yet, the default behavior of the standard library version of the array form is to simply forward to the corresponding single-object form. Would that not mean that ::operator new[](3)
, being equivalent (by default) to ::operator new(3)
, yields a pointer to storage only guaranteed to have 1-byte alignment, failing the above requirements?
Source: Windows Questions C++