简体   繁体   中英

Placement-new on array elements and pointer values

Consider the following three programs:

// program 1

#include<new>

struct A {
    const int a = 0;
    int b = 0;
};

int main() {
    auto a = new A[2];
    new(a+1) A;
    a[1].b = 1;
}
// program 2

#include<new>

struct A {
    const int a = 0;
    int b = 0;
};

int main() {
    auto a = new A[2];
    new(a) A;
    a[0].b = 1;
}
// program 3

#include<new>

struct A {
    const int a = 0;
    int b = 0;
};

int main() {
    auto a = new A[2];
    new(a) A;
    a->b = 1;
}

Do these programs have undefined behavior in C++17?

The problem I see is that according to [basic.life]/8 pointers will not automatically refer to the new A objects that I am creating via placement-new. std::launder is required explicitly to achieve that. Thus the member access will have undefined behavior as it is done on an object outside its lifetime.

At least for program 3 this seems clear to me, but for program 1, according to [intro.object]/2 the newly created object becomes a subobject of the array and so it should be reached via pointer arithmetic, shouldn't it?

And program 2 would then also not have undefined behavior, because the pointer arithmetic only requires a to point to an element of the array, not necessarily in its lifetime.

I believe that [basic.life]/8.3

the type of the original object is not const-qualified, and, if a class type, does not contain any non-static data member whose type is const-qualified or a reference type, and

Is the only clause that makes your member access code undefined behavior.

In all three cases a is the name of an array of two A objects so the member access is okay because you are using an A pointer to access an A object. You're not treating a char buffer as an A , you treating an A as and A which is allowed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM