2

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?

13
  • 3
    As far as I understand it (if I am wrong I like to be corrected): Pre C++17, only the unsigned data types where guaranteed to be aligned in memory char can be signed on some platforms. So in theory a char array could not be aligned causing issues when allocating allocating aligned objects Commented Jun 13 at 5:46
  • 1
    "are both UB". Citation needed. Commented Jun 13 at 6:13
  • 4
    If void* was not considered a valid storage type, how would you create an object in a memory block allocated by operator new, the return type of which is void*? The quote mentions a "special case", which implies that there are other cases as well. Commented Jun 13 at 6:46
  • 1
    This post is explaining the thing: stackoverflow.com/questions/79484153/… Commented Jun 13 at 9:02
  • 3
    Standard is trying to limit the number of valid types for uninitialized objects in ordere to maximize the extent of strict alaising, and optimizations that follow. char is widely used to keep text data, while usage of unsigned char is not versatile. Since C++20, std::byte has become the practical buffer data type. So in fresh and new code, you shouldn't even rely on unsigned char; Future standards may hopefully deprecate it. Commented Jun 13 at 16:16

1 Answer 1

1

The example you show isn't UB (if buf is suitably aligned and is big enough). "provides storage" affects whether the creation of the new object ends the lifetime of the array. But at least in the code snippet you show, whether buf's lifetime ends is immaterial.

As to why plain char isn't included in the "provides storage" rules...the committee apparently thought that it was a new thing so that it can have stricter rules. This is also consistent with the special treatment of unsigned char and std::byte for indeterminate and erroneous values.

Sign up to request clarification or add additional context in comments.

2 Comments

No, it's not. The new already produces a pointer to the created A object. Not that you are using ptr in any way for that to matter.
You are correct. Still another issue: the char array and A are not the same type, so they are defined in the otherwise subclause that means std::launder is needed. See the sections of Storage Reuse at en.cppreference.com/w/cpp/language/lifetime.html

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.