Does implicit object creation necessarily happen at storage return location?

21 hours ago 1
ARTICLE AD BOX

[intro.object]/13 describes the behavior of implicit object creation as:

Some operations are described as implicitly creating objects within a specified region of storage. For each operation that is specified as implicitly creating objects, that operation implicitly creates and starts the lifetime of zero or more objects of implicit-lifetime types ([basic.types.general]) in its specified region of storage if doing so would result in the program having defined behavior. If no such set of objects would give the program defined behavior, the behavior of the program is undefined. If multiple such sets of objects would give the program defined behavior, it is unspecified which such set of objects is created.

This paragraph specifies no restrictions on how many objects are created or where in the region of storage they can be created, as long as it's some combination of objects that would give the program defined behavior. So, there can be an object created at the beginning, there can be objects created not at the beginning, or both. And if no objects need to be created at all, then the implementation might create none.

But operations that return a "suitable created object" are subject to additional requirements per p14. The wording is very clear, in my view:

[...] These operations select one of the implicitly-created objects whose address is the address of the start of the region of storage, and produce a pointer value that points to that object. [...]

That means that, in contrast to operations that merely implicitly create objects, the ones that return a suitable created object are guaranteed to implicitly create an object at the beginning. They may also create zero or more objects implicitly that are not at the beginning: note that the sentence explicitly says "one of the implicitly-created objects", implying that the permission to create additional ones is not being taken away.

The reason why operations like malloc must always create an object at the beginning is that in C++ there's no such thing as a pointer value that doesn't yet point to any object but allows you to create an object there. [basic.compound]/3 defines the four kinds of pointer values: pointer to object/function, pointer past the end of an object, null pointer, and invalid pointer. Since malloc must not return pointers in the last three categories (in particular, invalid pointers can crash your program if you do so much as assign the pointer value to another pointer variable; [conv.lval]/3.3) it must create an object at the beginning so that it can return to you a pointer to that object. If you immediately perform explicit object creation at the returned pointer then it doesn't really matter what object malloc had implicitly created; you can't observe it anyway, but according to the standard, it did create something.

In the OP's program, operator new[] is first called, and it creates at least one object at the beginning of the returned storage, but you can't tell what kind of object it created, because the new-expression immediately creates 100 std::byte objects in the returned storage, which would "overwrite" whatever objects were created by operator new[]. But an operation that starts the lifetime of a std::byte array itself causes implicit object creation ([intro.object]/16) so at that point, an S object will be implicitly created at the location in which the rest of the program expects it to exist.

Read Entire Article