Рассмотрим следующие три программы:
// 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;
}
Есть ли у этих программ неопределенное поведение в C ++ 17?
Я вижу проблему в том, что согласно [basi c .life] / 8 указатели не будут автоматически ссылаться на новые A
объекты, которые я создаю с помощью размещения нового. std::launder
требуется для достижения этой цели. Таким образом, доступ к элементу будет иметь неопределенное поведение, как и в случае объекта вне его времени жизни.
По крайней мере для программы 3 это кажется мне понятным, но для программы 1, согласно [intro.object ] / 2 вновь созданный объект становится подобъектом массива, и поэтому к нему следует обращаться через арифметику указателя c, не так ли?
И тогда программа 2 также не будет иметь неопределенного поведения потому что арифметика указателя c требует только a
, чтобы указывать на элемент массива, а не обязательно на его время жизни.