struct T{
T(){}
~T(){}
};
int main(){
auto ptr = (T*)malloc(sizeof(T)*10); // #1
ptr++;
}
Since T is not an implicit-lifetime class, the operation malloc can never implicitly create an object of class type T. In this example, we intend to make ptr points to the initial element of the array object with 10 elements of type T. And based on this assumption, ptr++ would have a valid behavior. As per [intro.object] p11
Further, after implicitly creating objects within a specified region of storage, some operations are described as producing a pointer to a suitable created object. 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, if that value would result in the program having defined behavior.
Since an array of any type is an implicit-lifetime type, malloc(sizeof(T)*10) can implicitly create an array object with 10 elements and start the lifetime of that array object. Since the initial element and the containing array are not pointer-interconvertible, ptr can never point to the initial element of that array. Instead, the operation can only produce the pointer value of the array object. With this assumption, we should divide #1 into several steps to make the program well-formed?
// produce the pointer value points to array object of 10 T
auto arrPtr = (T(*)[10])malloc(sizeof(T)*10);
// decay the array
auto ptr =*arrPtr; // use array-to-pointer conversion
ptr++;
we should first get the array pointer and use that pointer value to acquire the initial element pointer value? Are these processes necessary in contributing to making the program well-formed?