What are the alignment limitations of the standard global default operator new?
c++, com, memory-alignment, visual-c++
Solution
5.3.4/1 [expr.new]
It is implementation-defined whether over-aligned types are supported (3.11).
One important thing here: `over-aligned` means more aligned than any built-in type. For example, on 64 bits machine, pointers are generally 8 bytes aligned and thus on those machines over-aligned means having an alignment strictly greater than 8.
Therefore, `over-aligned` is only of concern when using vector types, such as those required for SSE or AVX instructions or some variants of C/C++ (like Open CL). In day to day programming, the types you craft from the built-in types are never over-aligned.
§3.11 Alignment [basic.align]
3/ An extended alignment is represented by an alignment greater than `alignof(std::max_align_t)`. It is implementation-defined whether any extended alignments are supported and the contexts in which they are supported (7.6.2). A type having an extended alignment requirement is an over-aligned type.
9/ If a request for a specific extended alignment in a specific context is not supported by an implementation, the program is ill-formed. Additionally, a request for runtime allocation of dynamic storage for which the requested alignment cannot be honored shall be treated as an allocation failure.
Furthermore, it is customary for `new` to return memory aligned to `alignof(std::max_align_t)`. This is because the regular `::operator new` is only aware of the size of the object to allocate for, not of its alignment, and therefore need satisfy the strongest alignment requirements possible in the program.
On the other hand, beware of a `char` array allocated on the stack, there is no guarantee what its alignment would end up being.
Problem
I'm working on some older code that uses ATL's `CComBSTR` type. I'm changing it so that it will compile using Visual C++ Express Edition, which does not come with ATL. I used only a very small subset of `CComBSTR`, so doing this is fairly simple. However, when allocating the `BSTR` memory block, I need to fill the first four bytes with a 4 byte length prefix. I'm concerned that if I use a `new char[size]` expression to allocate the memory for the string, that I will cause alignment faults due to the allocated `char` array not having the correct alignment for the four byte prefix. Is there anything in the standard that states what alignment requirements the returned values of `new` have? All I see in C++11 are: 5.3.4/1 [expr.new] It is implementation-defined whether over-aligned types are supported (3.11). 3.11/6 [basic.align] The alignment requirement of a complete type can be queried using an alignof expression (5.3.6). Furthermore, the types char, signed char, and unsigned char shall have the weakest alignment requirement. [ Note: This enables the character types to be used as the underlying type for an aligned memory area (7.6.2).—end note ] I find this slightly confusing -- "weakest alignment requirement" says to me "least strict constraint on alignment", but the note under this seems to indicate the standard means the opposite. Am I safe using a `new char[sizeof(uint32_t) + 2*(length + 1)]` buffer as a `BSTR` like this? EDIT: I just realized that in this specific case of `BSTR`, one needs to use SysAllocString in order to allocate the string anyway; but I'm still interested in whether or not it is okay to use `new` in this way.