Невказане неявне створення об'єкта


9

Оскільки P0593 було прийнято неявне створення об'єктів для маніпулювання об'єктами низького рівня , об'єкти тепер можуть створюватися неявно в C ++ 20.

Зокрема, формулювання, введене пропозицією, дозволяє певним операціям (таким як std::malloc) автоматично створювати та запускати тривалість життя об'єктів певних типів, так званих неявних типів життя , якщо введення таких об'єктів спричиняє наявність програми з інакше невизначеною поведінкою визначена поведінка. Див. [Вступ.об’єкт] / 10 .

Тепер у проекті йдеться про те, що якщо є кілька наборів таких об'єктів, які можна було б створити неявно, щоб надати програмі певну поведінку, не визначено, який із цих наборів створюється. (Відповідне речення, здається, не присутнє в останній редакції пропозицій, до якої я міг отримати доступ, R5, але є в проекті комітету.)

Чи є насправді програма, для якої такий вибір неявно створеного набору об’єктів спостерігається? Іншими словами, чи існує програма з визначеною, але не визначеною поведінкою за допомогою цього нового правила, таким чином, що з висновку можна зробити висновки, які набори типів неявних об'єктів (з більш ніж одного можливого) були створені?

Або це речення було просто призначене для уточнення виконання програми на абстрактній машині (без помітного впливу)?


2
(ОТ), якщо імпліцитно створений об'єкт є цілим, чи можемо ми його назвати "імпліцитним"?
ММ

Здається незрозумілим, чи повинен бути відомий вибір елемента із невстановленого набору в точці малика
ММ

@MM Я припускав, що вибір набору вважався абстрактним як єдиний вибір для виконання всієї програми поза потоком виконання, але зі створенням відбувається безпосередньо під дією, про яку йдеться (тобто std::malloc), інакше у вас виникають проблеми з визначенням рекурсивно залежно від майбутнього.
волоський горіх

Я поставив ще одне запитання на цю тему, stackoverflow.com/questions/60627249 . Звичайно, деякі інші наслідки виникають на увазі, але одне питання за часом ..
ММ

Пропозиція стверджує, що неможливо так розрізнити, що важливо, оскільки немає можливості зробити вибір «правильно», лише оптимізації, щоб уникнути цього, було б ( дуже суворо) дійсним.
Девіс Оселедець

Відповіді:


9

Візьмемо приклад у стандарті та трохи його змінимо:

#include <cstdlib>
struct X { int a, b; };
X *make_x() {
  // The call to std::malloc implicitly creates an object of type X
  // and its subobjects a and b, and returns a pointer to that X object
  // (or an object that is pointer-interconvertible ([basic.compound]) with it),
  // in order to give the subsequent class member access operations
  // defined behavior.
  X *p = (X*)std::malloc(sizeof(struct X) * 2); // me: added the *2
  p->a = 1;
  p->b = 2;
  return p;
}

Раніше в цьому сховищі існував лише один набір дійсних об'єктів, які можна було неявно створити - він повинен був бути саме одним X. Але тепер у нас є сховище для двох Xs, але записуємо лише в один із них, і нічого в цій програмі ніколи не торкається решти байтів. Отже, існує безліч різних наборів об'єктів, які можна неявно створити - можливо, два Xs, можливо, Xі два ints, можливо, Xі восьми chars, ...

Який набір створено, не помітно, бо якби були фактичні спостереження, це зменшило б можливості лише до тих наборів, які були дійсними. Якщо ми зробили щось подібне, p[1]->a = 3тоді всесвіт можливостей руйнується лише до тієї, що має дві Xс.

Іншими словами, кілька наборів об'єктів, створених неявно, можливо лише тоді, коли в програмі недостатньо спостережень, щоб розрізнити їхню валідність. Якби існував спосіб розрізнити, то за визначенням вони не були б справедливими.


Це все-таки моє здогадування.
Баррі

Тому я вважаю, що просто не існує можливості розрізнити / спостерігати існування чи неіснуючі об'єкти різних неявних життєвих типів без невизначеної поведінки. У такому випадку мені здається, що це єдине використання " не визначеної поведінки " у стандарті, яке насправді не може призвести до різних результатів, що спостерігаються.
волоський горіх

1
Або що , якщо тільки доступи через glvalues типу [сорти] char, unsigned charабо std::byte? Об'єкт будь-якого тривіально копіюваного типу також може існувати там, я думаю?
асчеплер

2
Навіть у оригінальному прикладі також можливо створити об’єкт масиву разом з одним Xоб’єктом.
ТК
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.