I think the following code is ubiquitous:
struct A { ... };
char buf[1024];
auto ptr = new (buf) A(...);
However, new (buf) A(...); is UB. https://en.cppreference.com/w/cpp/language/lifetime.html says (emphasis mine):
As a special case, objects can be created in arrays of unsigned char or std::byte (since C++17) (in which case it is said that the array provides storage for the object) if:
- the lifetime of the array has begun and not ended
- the storage for the new object fits entirely within the array
- there is no array object that satisfies these constraints nested within the array.
Therefore, the char array is not considered as a valid storage type.
Why not allow the char array to be the argument of placement new?
void*was not considered a valid storage type, how would you create an object in a memory block allocated byoperator new, the return type of which isvoid*? The quote mentions a "special case", which implies that there are other cases as well.charis widely used to keep text data, while usage ofunsigned charis not versatile. Since C++20,std::bytehas become the practical buffer data type. So in fresh and new code, you shouldn't even rely onunsigned char; Future standards may hopefully deprecate it.