When you call placement new on a buffer:
A *a = new (buf) A;
you are invoking the built-in
void* operator new (std::size_t size, void* ptr) noexcept as defined in:
18.104.22.168 Placement forms [new.delete.placement]
These functions are reserved, a C++ program may not deﬁne functions that displace the versions in the Standard C++ library (17.6.4). The provisions of (3.7.4) do not apply to these reserved placement forms of operator new and operator delete.
void* operator new(std::size_t size, void* ptr) noexcept;
Remarks: Intentionally performs no other action.
The provisions of (3.7.4) include that the returned pointer should be suitably aligned, so it’s fine for
void* operator new (std::size_t size, void* ptr) noexcept to return a nonaligned pointer if one is passed in. This doesn’t let you off the hook, though:
 Note: when the allocation function returns a value other than null, it must be a pointer to a block of storage in which space for the object has been reserved. The block of storage is assumed to be appropriately aligned and of the requested size.
So if you pass unaligned storage to a placement-new expression you’re violating the assumption that the storage is aligned, and the result is UB.
Indeed, in your program above, if you replace
long long b with
__m128 b (after
#include ) then the program will segfault, as expected.
Originally posted 2013-11-09 23:20:38.