Do the library versions of alignment-unaware array allocation functions meet the requirements on alignment?

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 type std​::​align_­val_­t, the storage will have the alignment specified by the value of this argument.
(3.2) — Otherwise, if the allocation function is named operator 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++

LEAVE A COMMENT